IT民工
加油!

线段树的成段更新,区间求和基础题。

/*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;
}
posted on 2012-07-24 14:07  找回失去的  阅读(205)  评论(0编辑  收藏  举报