http://acm.hdu.edu.cn/showproblem.php?pid=4348
以前做的主席树没有做过在线修改的题做一下(主席树这种东西正经用法难道不是在线修改吗),标记永久化比较方便。
前面眼瞎爆了一次空间改过来之后交第二次奇迹一样a了,好久没有1A过了(泪)。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define LL long long 8 const int maxn=100100; 9 int n,m; 10 char s[4]={}; 11 int t[maxn]={},shu[maxn]={},lc[maxn*30]={},rc[maxn*30]={}; 12 LL sum[maxn*30]={},ad[maxn*30]={},cnt=0; 13 int tot=0; 14 void build(int &x,int l,int r){ 15 x=++tot; 16 //cout<<l<<r<<endl; 17 if(l==r){scanf("%lld",&sum[x]); return;} 18 int mid=(l+r)/2; 19 build(lc[x],l,mid); 20 build(rc[x],mid+1,r); 21 sum[x]=sum[lc[x]]+sum[rc[x]]; 22 } 23 void updata(int x,int l,int r){ 24 sum[x]=sum[lc[x]]+sum[rc[x]]+ad[x]*(LL)(r-l+1); 25 } 26 void getadd(int &x,int y,int l,int r,int zl,int zr,LL z){ 27 x=++tot;sum[x]=sum[y];ad[x]=ad[y];lc[x]=lc[y];rc[x]=rc[y]; 28 if(zl<=l&&r<=zr){sum[x]=sum[y]+z*(LL)(r-l+1);ad[x]+=z; return;} 29 int mid=(l+r)/2; 30 if(zl<=mid)getadd(lc[x],lc[y],l,mid,zl,zr,z); 31 if(mid<zr)getadd(rc[x],rc[y],mid+1,r,zl,zr,z); 32 updata(x,l,r); 33 } 34 LL gethis(int x,int l,int r,int zl,int zr,LL zhi){ 35 if(zl<=l&&r<=zr){return sum[x]+zhi*(LL)(r-l+1);} 36 int mid=(l+r)/2;LL ans=0; 37 if(zl<=mid)ans+=gethis(lc[x],l,mid,zl,zr,zhi+ad[x]); 38 if(mid<zr)ans+=gethis(rc[x],mid+1,r,zl,zr,zhi+ad[x]); 39 return ans; 40 } 41 int main(){ 42 int fla=0; 43 while(~scanf("%d%d",&n,&m)){ 44 if(fla)printf(" ");++fla; 45 tot=0;cnt=0; 46 build(t[0],1,n);shu[0]=tot; 47 int x,y,z; 48 for(int i=1;i<=m;i++){ 49 scanf("%s",s); 50 if(s[0]=='C'){ 51 scanf("%d%d%d",&x,&y,&z); 52 cnt++;t[cnt]=t[cnt-1]; 53 getadd(t[cnt],t[cnt],1,n,x,y,z); 54 shu[cnt]=tot; 55 } 56 else if(s[0]=='Q'){ 57 scanf("%d%d",&x,&y); 58 printf("%lld ",gethis(t[cnt],1,n,x,y,0)); 59 } 60 else if(s[0]=='H'){ 61 scanf("%d%d%d",&x,&y,&z); 62 printf("%lld ",gethis(t[z],1,n,x,y,0)); 63 } 64 else{ 65 scanf("%d",&x); 66 cnt=x;tot=shu[x]; 67 } 68 } 69 } 70 return 0; 71 }