BZOJ3212: Pku3468 A Simple Problem with Integers

【传送门:BZOJ3212


简要题意:

  给出n个点,每个点有点权,Q个询问,两种询问:

  Q x y求出第x个点到第y个点的点权和

  C x y c将第x个点到第y个点的点权都增加c


题解:

  裸线段树

  注意加long long


参考代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
struct node
{
    int l,r,lc,rc;LL c,lazy;
}tr[210000];int trlen;
void bt(int l,int r)
{
    trlen++;int now=trlen;
    tr[now].l=l;tr[now].r=r;tr[now].c=tr[now].lazy=0;
    tr[now].lc=tr[now].rc=-1;
    if(l<r)
    {
        int mid=(l+r)/2;
        tr[now].lc=trlen+1;bt(l,mid);
        tr[now].rc=trlen+1,bt(mid+1,r);
    }
}
void update(int now)
{
    int lc=tr[now].lc,rc=tr[now].rc;
    if(lc!=-1)
    {
        tr[lc].c+=LL(tr[lc].r-tr[lc].l+1)*tr[now].lazy;
        tr[lc].lazy+=tr[now].lazy;
    }
    if(rc!=-1)
    {
        tr[rc].c+=LL(tr[rc].r-tr[rc].l+1)*tr[now].lazy;
        tr[rc].lazy+=tr[now].lazy;
    }
    tr[now].lazy=0;
}
void follow(int now)
{
    int lc=tr[now].lc,rc=tr[now].rc;
    tr[now].c=tr[lc].c+tr[rc].c;
}
void change(int now,int l,int r,LL c)
{
    if(tr[now].l==l&&tr[now].r==r)
    {
        tr[now].c+=LL(r-l+1)*c;
        tr[now].lazy+=c;
        return ;
    }
    int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
    if(tr[now].lazy!=0) update(now);
    if(r<=mid) change(lc,l,r,c);
    else if(l>mid) change(rc,l,r,c);
    else change(lc,l,mid,c),change(rc,mid+1,r,c);
    follow(now);
}
LL findsum(int now,int l,int r)
{
    if(tr[now].l==l&&tr[now].r==r) return tr[now].c;
    int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
    if(tr[now].lazy!=0) update(now);
    if(r<=mid) return findsum(lc,l,r);
    else if(l>mid) return findsum(rc,l,r);
    else return findsum(lc,l,mid)+findsum(rc,mid+1,r);
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    trlen=0;bt(1,n);
    for(int i=1;i<=n;i++)
    {
        LL x;
        scanf("%lld",&x);
        change(1,i,i,x);
    }
    char st[3];
    for(int i=1;i<=m;i++)
    {
        int x,y;LL c;
        scanf("%s%d%d",st+1,&x,&y);
        if(st[1]=='Q') printf("%lld\n",findsum(1,x,y));
        else
        {
            scanf("%lld",&c);
            change(1,x,y,c);
        }
    }
    return 0;
}

 

posted @ 2018-04-16 21:09  Star_Feel  阅读(147)  评论(0编辑  收藏  举报