记录
(调不出来我就去用下标替代指针重写了)
#include <iostream>
using namespace std;
#define int long long
#define N 1000150
struct Node {
int u;
int v;
Node *lc, *rc;
int l, r, mid;
int lazy; // 懒标记
void init(int L, int R) {
l = L;
r = R;
mid = l + r >> 1;
}
} tr[N * 4];
int n, m;
int x, y, k;
int ori[N];
char beh;
int t1, t2, t3;
Node* tail = tr;
void push_up(Node* nod) {
nod->v = nod->lc->v + nod->rc->v;
}
void build(Node* nod, int L, int R) {
nod->init(L, R);
if (L == R) {
nod->v = ori[L];
nod->lc = nod->rc = tr;
return;
}
nod->lc = (++tail);
build(tail, L, nod->mid);
nod->rc = (++tail);
build(tail, nod->mid + 1, R);
push_up(nod);
}
void push_down(Node* nod) {
nod->lc->lazy += nod->lazy;
nod->rc->lazy += nod->lazy;
nod->lc->v += (nod->mid - nod->l + 1) * nod->lazy;
nod->rc->v += (nod->r - nod->mid) * nod->lazy;
nod->lazy = 0;
}
void modify(Node* nod, int L, int R, int v) {
if (L <= nod->l && R >= nod->r) {
nod->lazy += v;
nod->v += (nod->r - nod->l + 1) * v;
} else {
push_down(nod);
if (nod->mid < R) {
modify(nod->rc, nod->mid + 1, R, v);
}
if (nod->mid >= L) {
modify(nod->lc, L, nod->mid, v);
}
push_up(nod);
}
}
int query(Node* nod, int L, int R) {
if (nod->r == R && nod->l == L) {
return nod->v;
}
push_down(nod);
if (nod->mid >= R) {
return query(nod->lc, L, nod->mid);
} else if (nod->mid < L) {
return query(nod->rc, nod->mid + 1, R);
} else {
return query(nod->lc, L, nod->mid) + query(nod->rc, nod->mid + 1, R);
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> ori[i];
}
build(++tail, 1, n);
while (m--) {
cin >> beh;
if (beh == '1') {
cin >> t1 >> t2 >> t3;
modify(tr + 1, t1, t2, t3);
} else {
cin >> t1 >> t2;
cout << query(tr + 1, t1, t2) << endl;
}
}
return 0;
}