intquery(int L, int R) { int res = 0; for (L += T - 1, R += T + 1; L ^ R ^ 1; L >>= 1, R >>= 1, cur <<= 1) { if (~L & 1) res += tr[L ^ 1].sum; if (R & 1) res += tr[R ^ 1].sum; } return res; }
/* RMQ int query(int L, int R) { int res = INF; for (L += T - 1, R += T + 1; L ^ R ^ 1; L >>= 1, R >>= 1) { if (~L & 1) res = min(res, minn[L ^ 1]); if (R & 1) res = min(res, minn[R ^ 1]); } return res; } */
voidmodify(int L, int R, int k) { int lft = 0, rht = 0, cur = 1; for (L += T - 1, R += T + 1; L ^ R ^ 1; L >>= 1, R >>= 1, cur <<= 1) { tr[L].sum += k * lft, tr[R].sum += k * rht; if (~L & 1) tr[L ^ 1].tag += k, tr[L ^ 1].sum += k * cur, lft += cur; if (R & 1) tr[R ^ 1].tag += k, tr[R ^ 1].sum += k * cur, rht += cur; } for (; L && R; L >>= 1, R >>= 1) tr[L].sum += k * lft, tr[R].sum += k * rht; }
区间查询
和修改一样,维护好三个变量即可,遇到了标记加上即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
intquery(int L, int R) { int lft = 0, rht = 0, cur = 1, res = 0; for (L += T - 1, R += T + 1; L ^ R ^ 1; L >>= 1, R >>= 1, cur <<= 1) { if (tr[L].tag) res += tr[L].tag * lft; if (tr[R].tag) res += tr[R].tag * rht; if (~L & 1) res += tr[L ^ 1].sum, lft += cur; if (R & 1) res += tr[R ^ 1].sum, rht += cur; } for (; L && R; L >>= 1, R >>= 1) res += tr[L].tag * lft + tr[R].tag * rht; return res; }
template<typename Type> inlinevoidread(Type& res) { res = 0; int ch = getchar(), flag = 0; while (!isdigit(ch)) flag |= ch == '-', ch = getchar(); while (isdigit(ch)) res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar(); res = flag ? -res : res; } template<typename Type, typename... Args> inlinevoidread(Type& res, Args&... y){ read(res), read(y...); }
int n, m, a[N];
structZKWSegment { structNode { int sum, tag; } tr[N << 1]; int T;
voidbuild(int L, int R) { T = 1 << (int)ceil(log2(R - L + 2)); for (int i = 1; i <= n; i ++) tr[T + i].sum = a[i]; for (int i = T - 1; i >= 1; i --) tr[i].sum = tr[i << 1].sum + tr[i << 1 | 1].sum; }
voidmodify(int L, int R, int k) { int lft = 0, rht = 0, cur = 1; for (L += T - 1, R += T + 1; L ^ R ^ 1; L >>= 1, R >>= 1, cur <<= 1) { tr[L].sum += k * lft, tr[R].sum += k * rht; if (~L & 1) tr[L ^ 1].tag += k, tr[L ^ 1].sum += k * cur, lft += cur; if (R & 1) tr[R ^ 1].tag += k, tr[R ^ 1].sum += k * cur, rht += cur; }
for (; L && R; L >>= 1, R >>= 1) tr[L].sum += k * lft, tr[R].sum += k * rht; }
intquery(int L, int R) { int lft = 0, rht = 0, cur = 1, res = 0; for (L += T - 1, R += T + 1; L ^ R ^ 1; L >>= 1, R >>= 1, cur <<= 1) { if (tr[L].tag) res += tr[L].tag * lft; if (tr[R].tag) res += tr[R].tag * rht; if (~L & 1) res += tr[L ^ 1].sum, lft += cur; if (R & 1) res += tr[R ^ 1].sum, rht += cur; }
for (; L && R; L >>= 1, R >>= 1) res += tr[L].tag * lft + tr[R].tag * rht; return res; }
} SGT;
signedmain() { read(n, m); for (int i = 1; i <= n; i ++) read(a[i]); SGT.build(1, n);
for (int i = 1, opt, x, y, k; i <= m; i ++) { read(opt, x, y); if (opt == 1) { read(k); SGT.modify(x, y, k); } else cout << SGT.query(x, y) << '\n'; }