线段树的成段更新,区间求和基础题。
/*Accepted 4284K 1750MS C++ 1946B 2012-07-24 14:01:14*/ #include<cstdio> #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 typedef long long LL; const int MAXN = 100005; LL add[MAXN << 2]; LL sum[MAXN << 2]; void PushUp( int rt ) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } void PushDown( int l, int r, int rt) { int ls = rt << 1, rs = rt << 1 | 1, m = (l + r) >> 1; if( add[rt]) { add[ls] += add[rt]; add[rs] += add[rt]; sum[ls] += add[rt] * ( m - l + 1); sum[rs] += add[rt] * ( r - m); add[rt] = 0; } } 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 L, int R, LL c, int l, int r, int rt) { int m = (l + r) >> 1; if( L <= l && r <= R) { add[rt] += c; sum[rt] += ( r - l + 1) * c; return; } PushDown( l, r, rt); if( L <= m) update(L, R, c, lson); if( R > m) update(L, R, c, rson); PushUp(rt); } LL query( int L, int R, int l, int r, int rt) { int m = (l + r) >> 1; LL ret = 0; if( L <= l && r <= R) { return sum[rt]; } PushDown(l, r, rt); if( L <= m) ret += query(L, R, lson); if( R > m) ret += query(L, R, rson); return ret; } int main() { int n, q; while( scanf( "%d%d", &n, &q) == 2) { build( 1, n, 1); while( q --) { char s[2]; int a, b; LL c; scanf( "%s", s); if( 'C' == s[0]){ scanf( "%d%d%lld", &a, &b, &c); update( a, b, c, 1, n, 1); } if( 'Q' == s[0]){ scanf( "%d%d", &a, &b); printf( "%lld\n", query( a, b, 1, n, 1)); } } } return 0; }