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; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚