dreamxr
精诚所至,金石为开!

导航

 

【题目描述】

给定一个区间及区间上的数,每次有一个操作,在某段区间上加某个数后者询问某段区间的和。

【思路】

线段树的成段更新,要用到lazy_tag,要注意int会超范围,别的没什么了,最近学习了下hh大牛的线段树风格,学习下。

#include<cstdio>
#define N 100010
#define lson l,mid,n<<1
#define rson mid+1,r,n<<1|1
typedef long long LL;
using namespace std;
LL sum[N<<2],add[N<<2];
void  build(int l,int r,int n){
    add[n]=0;
    if(l==r){
        scanf("%lld",&sum[n]);
        return ;
    }
    int mid=(l+r)>>1;
     build(lson);
     build(rson);
     sum[n]=sum[n<<1]+sum[n<<1|1];
}
void update(int ll,int rr,int aa,int l,int r,int n){
    if(ll==l&&rr==r){
        add[n]+=(LL)aa;
        sum[n]+=(LL)aa*(r-l+1);
        return;
    }
    int m=r-l+1;
    if(add[n]!=0){
        add[n<<1]+=add[n];
        add[n<<1|1]+=add[n];
        sum[n<<1]+=add[n]*(m-(m>>1));
        sum[n<<1|1]+=add[n]*(m>>1);
        add[n]=0;
    }
    int mid=(l+r)>>1;
    if(rr<=mid)
    update(ll,rr,aa,lson);
    else if(ll>mid)
    update(ll,rr,aa,rson);
    else
    update(ll,mid,aa,lson),update(mid+1,rr,aa,rson);
    sum[n]=sum[n<<1]+sum[n<<1|1];
}
LL query(int ll,int rr,int l,int r,int n){
    if(ll==l&&rr==r)
    return sum[n];
    int m=r-l+1;
    if(add[n]!=0){
        add[n<<1]+=add[n];
        add[n<<1|1]+=add[n];
        sum[n<<1]+=add[n]*(m-(m>>1));
        sum[n<<1|1]+=add[n]*(m>>1);
        add[n]=0;
    }
    int mid=(l+r)>>1;
    if(rr<=mid)
    return query(ll,rr,lson);
    else if(ll>mid)
    return  query(ll,rr,rson);
    else
    return query(ll,mid,lson)+query(mid+1,rr,rson);
}
int main(){
    int n,q;
    while(~scanf("%d%d",&n,&q)){
        build(1,n,1);
        while(q--){
            char s;
            int a,b,c;
            getchar();
            scanf("%c",&s);
            if(s=='Q'){
                scanf("%d%d",&a,&b);
                printf("%lld\n",query(a,b,1,n,1));
            }
            else if(s=='C'){
                scanf("%d%d%d",&a,&b,&c);
                update(a,b,c,1,n,1);
            }
        }
    }
    return 0;
}
posted on 2012-07-06 23:09  dreamxr  阅读(104)  评论(0)    收藏  举报