HDU 4348 To the moon 主席树 在线更新

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 }
View Code

原文地址:https://www.cnblogs.com/137shoebills/p/8858793.html