K_func @ 2024-12-14 17:09:24
#include <bits/stdc++.h>
using namespace std;
template<typename _Tp>
class segment_tree {
protected:
int n, root, n4, _end;
vector<_Tp> tree, lazy;
vector<_Tp> *arr;
vector<bool> is_lazy;
void maintain(int l, int r, int p) {
int mid = l + (r - l) / 2;
if (l != r && is_lazy[p]) {
lazy[p * 2] = lazy[p];
is_lazy[p * 2] = true;
lazy[p * 2 + 1] = lazy[p];
is_lazy[p * 2 + 1] = true;
tree[p * 2] = lazy[p] * (mid - l + 1);
tree[p * 2 + 1] = lazy[p] * (r - mid);
lazy[p] = 0;
is_lazy[p] = 0;
}
}
_Tp range_sum(int l, int r, int cl, int cr, int p) {
if (l <= cl && r <= cr) return tree[p];
int mid = cl + (cr - cl) / 2;
_Tp sum = 0;
maintain(cl, cr, p);
if (l <= mid) {
sum += range_sum(l, r, cl, mid, p * 2);
}
if (r > mid) {
sum += range_sum(l, r, mid + 1, cr, p * 2 + 1);
}
return sum;
}
void range_set(int l, int r, _Tp val, int cl, int cr, int p) {
if (l <= cl && r <= cr) {
lazy[p] = val;
is_lazy[p] = 1;
tree[p] = (cr - cl + 1) * val;
}
int mid = cl + (cr - cl) / 2;
maintain(cl, cr, p);
if (l <= mid) {
range_set(l, r, val, cl, mid, p * 2);
}
if (r > mid) {
range_set(l, r, val, mid + 1, cr, p * 2 + 1);
}
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
void range_add(int l, int r, _Tp val, int cl, int cr, int p) {
if (l <= cl && cr <= r) {
lazy[p] += val;
tree[p] += (cr - cl + 1) * val;
return;
}
int m = cl + (cr - cl) / 2;
maintain(cl, cr, p);
if (l <= m) range_add(l, r, val, cl, m, p * 2);
if (r > m) range_add(l, r, val, m + 1, cr, p * 2 + 1);
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
void build(int s, int t, int p) {
if (s == t) {
tree[p] = (*arr)[s];
return ;
}
int mid = s + (t - s) / 2;
build(s, mid, p * 2);
build(mid + 1, t, p * 2 + 1);
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
public:
explicit segment_tree<_Tp>(vector<_Tp> v) {
n = v.size();
n4 = n * 4;
tree = vector<_Tp>(n4, 0);
lazy = vector<_Tp>(n4, 0);
is_lazy = vector<bool>(n4, 0);
arr = &v;
_end = n - 1;
root = 1;
build(0, _end, 1);
arr = nullptr;
}
_Tp rsum(int l, int r) {
return range_sum(l, r, 0, _end, root);
}
void rset(int l, int r, _Tp val) {
return range_set(l, r, val, 0, _end, root);
}
void radd(int l, int r, _Tp val) {
return range_add(l, r, val, 0, _end, root);
}
};
int n, m;
int main() {
cin >> n >> m;
vector<long long> arr(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
segment_tree<long long> st(arr);
for (int i = 0; i < m; i++) {
int op;
cin >> op;
if (op) {
int a, b, c;
cin >> a >> b >> c;
st.radd(a, b, c);
} else {
int a, b;
cin >> a >> b;
cout << st.rsum(a, b) << endl;
}
}
return 0;
}