http://poj.org/problem?id=3468
/*2266ms,4508KB*/ #include <cstdio> #include <algorithm> using namespace std; #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 #define root 1, N, 1 #define LL long long const int maxn = 100000; LL sum[maxn << 2], add[maxn << 2]; inline void pushup(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } inline void pushdown(int rt, int m) { if (add[rt]) { add[rt << 1] += add[rt]; add[rt << 1 | 1] += add[rt];///更新左右子区间add sum[rt << 1] += add[rt] * (m - (m >> 1)); sum[rt << 1 | 1] += add[rt] * (m >> 1);///平分父节点add,更新左右子区间和 add[rt] = 0;///父节点add清零 } } void build(int l, int r, int rt) { add[rt] = 0; if (l == r) { scanf("%lld", &sum[rt]); return; } int m = (l + r) >> 1; build(lson); build(rson); pushup(rt); } void update(int ql, int qr, int c, int l, int r, int rt) { if (ql <= l && r <= qr) { add[rt] += c;///存至此,不再往下更新 sum[rt] += (LL)c * (r - l + 1); return; } pushdown(rt , r - l + 1);///用父节点add往下细分计算 int m = (l + r) >> 1; if (ql <= m) update(ql, qr, c, lson); if (qr > m) update(ql, qr, c, rson); pushup(rt); } LL query(int ql, int qr, int l, int r, int rt) { if (ql <= l && r <= qr) { return sum[rt]; } pushdown(rt , r - l + 1);///用父节点add往下细分计算 int m = (l + r) >> 1; LL ret = 0; if (ql <= m) ret += query(ql, qr, lson); if (qr > m) ret += query(ql, qr, rson); return ret; } int main() { int N, Q, a, b, c; scanf("%d%d", &N, &Q); build(root); while (Q--) { getchar(); if (getchar() == 'Q') { scanf("%d%d", &a, &b); printf("%lld\n", query(a, b, root)); } else { scanf("%d%d%d", &a, &b, &c); update(a, b, c, root); } } return 0; }