BZOJ 3212 Pku3468 A Simple Problem with Integers

2017.09.20

题目大意

维护一个序列,支持区间加法,区间求和。


裸线段树板子,直接上就好了= =

#include <cstdio>
#include <algorithm>
using namespace std;
#define lson pos<<1
#define rson pos<<1|1
int n,q,m,a[100010],inx,iny,inz;
long long val[400010],laz[400010];
char mode[10];
void pushup(int pos) {val[pos]=val[lson]+val[rson];}
void pushdown(int pos,int l,int r)
{
    if(laz[pos])
    {
        int mid=(l+r)>>1;
        laz[lson]+=laz[pos],laz[rson]+=laz[pos];
        val[lson]+=laz[pos]*(mid-l+1),val[rson]+=laz[pos]*(r-mid);
        laz[pos]=0;
    }
}
void build(int pos,int l,int r)
{
    if(l==r)
    {
        val[pos]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(pos);
}
void update(int pos,int l,int r,int x,int y,int z)
{
    if(x<=l&&r<=y)
    {
        val[pos]+=(r-l+1)*z;
        laz[pos]+=z;
        return;
    }
    int mid=(l+r)>>1;
    pushdown(pos,l,r);
    if(x<=mid) update(lson,l,mid,x,y,z);
    if(y>mid) update(rson,mid+1,r,x,y,z);
    pushup(pos);
    return;
}
long long query(int pos,int l,int r,int x,int y)
{
    if(x<=l&&r<=y) return val[pos];
    int mid=(l+r)>>1;
    pushdown(pos,l,r);
    long long ret=0;
    if(x<=mid) ret+=query(lson,l,mid,x,y);
    if(y>mid) ret+=query(rson,mid+1,r,x,y);
    return ret;
}
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i) scanf("%d",a+i);
    build(1,1,n);
    while(q--)
    {
        scanf("%s",mode);
        if(mode[0]=='C')
        {
            scanf("%d%d%d",&inx,&iny,&inz);
            update(1,1,n,inx,iny,inz);
        }
        if(mode[0]=='Q')
        {
            scanf("%d%d",&inx,&iny);
            printf("%lld\n",query(1,1,n,inx,iny));
        }
    }
    return 0;
}