POJ3468(A Simple Problem with Integers)

维持一个整数序列,支持2种操作:

Q a b:查询区间[a,b]内的和;

C a b x:将区间[a,b]内的每个数加上x。

对于每次查询输出结果。

结果可能会超32位。

View Code
#include <stdio.h>
#define N 100001
int n,m,a[N];
long long ans;
long long sum[4*N],inc[4*N];
void update(int cur)
{
    int ls=cur<<1,rs=cur<<1|1;
    sum[cur]=sum[ls]+sum[rs];
}
void pushdown(int cur,int x,int y)
{
    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;
    if(inc[cur])
    {
        sum[ls]+=inc[cur]*(mid-x+1);
        sum[rs]+=inc[cur]*(y-mid);
        inc[ls]+=inc[cur];
        inc[rs]+=inc[cur];
        inc[cur]=0;
    }
}
void build(int cur,int x,int y)
{
    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;
    inc[cur]=0;
    if(x==y)
    {
        sum[cur]=a[x];
        return;
    }
    build(ls,x,mid);
    build(rs,mid+1,y);
    update(cur);
}
void change(int cur,int x,int y,int s,int t,int v)
{
    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;
    if(x>=s && y<=t)
    {
        sum[cur]+=v*(y-x+1);
        inc[cur]+=v;
        return;
    }
    pushdown(cur,x,y);
    if(mid>=s)  change(ls,x,mid,s,t,v);
    if(mid+1<=t)    change(rs,mid+1,y,s,t,v);
    update(cur);
}
void query(int cur,int x,int y,int s,int t)
{
    int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1;
    if(x>=s && y<=t)
    {
        ans+=sum[cur];
        return;
    }
    pushdown(cur,x,y);
    if(mid>=s)  query(ls,x,mid,s,t);
    if(mid+1<=t)    query(rs,mid+1,y,s,t);
}
int main()
{
    int i,x,y,z;
    char c;
    while(~scanf("%d%d",&n,&m))
    {
        for(i=1;i<=n;i++)   scanf("%d",&a[i]);
        build(1,1,n);
        for(i=0;i<m;i++)
        {
            c=0;
            while(c!='Q' && c!='C') scanf("%c",&c);
            scanf("%d%d",&x,&y);
            if(c=='Q')
            {
                ans=0;
                query(1,1,n,x,y);
                printf("%lld\n",ans);
            }
            else
            {
                scanf("%d",&z);
                change(1,1,n,x,y,z);
            }
        }
    }
    return 0;
}
posted @ 2012-07-12 13:15  BeatLJ  阅读(247)  评论(0编辑  收藏  举报