线段树功能
update:成段更新 query:区间求和
#include <iostream> #include <string> #include <cstdio> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; typedef long long ll; const int MAXN = 111111; ll sum[MAXN<<2], add[MAXN<<2]; void push_up(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void push_down(int rt, int len) { if(add[rt] == 0) return; add[rt<<1] += add[rt]; add[rt<<1|1] += add[rt]; sum[rt<<1] += (len - (len >> 1)) * add[rt]; sum[rt<<1|1] += (len >> 1) * add[rt]; add[rt] = 0; } void build(int l, int r, int rt) { add[rt] = 0; if(l == r) { scanf("%I64d", &sum[rt]); return; } int m = (l + r) >> 1; build(lson); build(rson); push_up(rt); } void update(int L, int R, int c, int l, int r, int rt) { if(L <= l && r <= R) { sum[rt] += c * (r - l + 1); add[rt] += c; return; } push_down(rt, r-l+1); int m = (l + r) >> 1; if(L <= m) update(L, R, c, lson); if(R > m) update(L, R, c, rson); push_up(rt); } ll query(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) return sum[rt]; push_down(rt, r-l+1); int m = (l + r) >> 1; ll ret = 0; if(L <= m) ret += query(L, R, lson); if(R > m) ret += query(L, R, rson); return ret; } int main() { // freopen("in.txt", "r" ,stdin); int N, Q; while(~scanf("%d%d", &N, &Q)) { build(1, N, 1); while(Q--) { int a, b, c; char s[3]; scanf("%s", s); scanf("%d%d", &a, &b); if(s[0] == 'Q') printf("%I64d\n", query(a, b, 1, N, 1)); else { scanf("%d", &c); update(a, b, c, 1, N, 1); } } } return 0; }