POJ3468 A Simple Problem with Integers 區間更新
阿新 • • 發佈:2018-12-19
#include<cstdio> #include<istream> using namespace std; typedef long long ll; const int MAX=1e5+10; //#define lson l,m,rt<<1 //#define rson m+1,r,rt<<1|1 ll sum[MAX<<2],add[MAX<<2]; //利用add做延遲標記 struct Node{ int l,r; int mid(){ return (l+r)>>1; } }tree[MAX<<2]; void PushUp(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void PushDown(int rt,int m){ if(add[rt]){ add[rt<<1]+=add[rt]; add[rt<<1|1]+=add[rt]; sum[rt<<1]+=add[rt]*(m-(m>>1)); sum[rt<<1|1]+=add[rt]*(m>>1); add[rt]=0; } } void Build(int l,int r,int rt){ tree[rt].l=l; tree[rt].r=r; add[rt]=0; if(l==r){ scanf("%I64d",&sum[rt]); return ; } int m=tree[rt].mid(); Build(l,m,rt<<1); Build(m+1,r,rt<<1|1); PushUp(rt); } void Update(int c,int l,int r,int rt){ if(tree[rt].l==l&&tree[rt].r==r){ add[rt]+=c; sum[rt]+=(ll)c*(r-l+1); return ; } if(tree[rt].l==tree[rt].r) return ; PushDown(rt,tree[rt].r-tree[rt].l+1); int m=tree[rt].mid(); if(r<=m) Update(c,l,r,rt<<1); else if(l>m) Update(c,l,r,rt<<1|1); else{ Update(c,l,m,rt<<1); Update(c,m+1,r,rt<<1|1); } PushUp(rt); } ll Query(int l,int r,int rt){ if(l==tree[rt].l&&r==tree[rt].r) return sum[rt]; PushDown(rt,tree[rt].r-tree[rt].l+1); int m=tree[rt].mid(); ll res=0; if(r<=m) res+=Query(l,r,rt<<1); else if(l>m) res+=Query(l,r,rt<<1|1); else{ res+=Query(l,m,rt<<1); res+=Query(m+1,r,rt<<1|1); } return res; } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ Build(1,n,1); while(m--){ char ch[2]; scanf("%s",ch); int a,b,c; if(ch[0]=='Q'){ scanf("%d%d",&a,&b); printf("%lld\n",Query(a,b,1)); } else{ scanf("%d%d%d",&a,&b,&c); Update(c,a,b,1); } } } }