POJ A Simple Problem with Integers 3468(线段树区间更新)

   注意在查询的时候还要进行更新。


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#define LL long long
#define inf 0x3f3f3f3f
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
LL n,sum[1000100],la[1000100];

using namespace std;

void up(LL rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(LL rt,LL len)
{
    if(la[rt])
    {
        la[rt<<1]+=la[rt];
        la[rt<<1|1]+=la[rt];
        sum[rt<<1]+=la[rt]*(len-(len>>1));
        sum[rt<<1|1]+=la[rt]*(len>>1);
        la[rt]=0;
    }
}
void bu(LL l,LL r,LL rt)
{
    la[rt]=0;
    if(l==r)
    {
        scanf("%lld",&sum[rt]);
        return ;
    }
    LL mid=(l+r)>>1;
    bu(ls);
    bu(rs);
    up(rt);
}
void ch(LL a,LL b,LL c,LL l,LL r,LL rt)
{
    if(a<=l&&r<=b)
    {
        la[rt]+=c;
        sum[rt]+=(r-l+1)*c;
        return ;
    }
    pushdown(rt,r-l+1);
    LL mid=(l+r)>>1;
    if(a<=mid)
        ch(a,b,c,ls);
    if(b>mid)
        ch(a,b,c,rs);
    up(rt);
}
LL Q(LL a,LL b,LL l,LL r,LL rt)
{
    if(a<=l&&r<=b)
    {
        return sum[rt];
    }
    pushdown(rt,r-l+1);
    LL mid=(l+r)>>1;
    LL s=0;
    if(a<=mid)
        s+=Q(a,b,ls);
    if(mid<b)
        s+=Q(a,b,rs);
    return s;
}
int main()
{
    LL m,i,j,cla,a,b,c;char st[10];
    scanf("%lld%lld",&n,&m);
        getchar();
        bu(1,n,1);
        while(m--)
        {
            scanf("%s",&st);
            if( !strcmp( st,"Q" ) )
            {
               scanf("%lld%lld",&a,&b);
               LL p=Q(a,b,1,n,1);
               printf("%lld\n",p);
            }
            else if(!strcmp(st,"C") )
            {
                scanf("%lld%lld%lld",&a,&b,&c);
                ch(a,b,c,1,n,1);
            }
        }

    return 0;
}


你可能感兴趣的:(线段树)