BZOJ 1500 维修数列【Splay】

注意:1,内存限制,所以需要回收删除的点

   2,当前节点的左连续区间和最大值=max(左子树的左连续区间和最大值,左子树的总和+当节点的值+max(右子树的左连续区间和最大值,0));右连续区间和最大值同理

     当前节点的区间和最大值=max(左子树的区间和最大值,max(右子树的区间和最大值,max(左子树的右连续区间和最大值,0)+max(右子树的左连续区间和最大值,0)+当前节点的值))

   3,pushdown时,应该交换左子树的左连续区间和最大值与左子树的右连续区间和最大值。因为向上更新时这两个值的不同对结果有影响,不能延迟更新。

  1 #include<stdio.h> 
  2 #include<string.h>
  3 #include<iostream>
  4 using namespace std;
  5 const int N=500100;
  6 const int INF=0x7fffffff;
  7 int data[N],fa[N],id,root; 
  8 int size[N],sum[N],a[N];
  9 int t[N][2],st[N],top;
 10 int mxl[N],mxr[N],mxm[N];
 11 int same[N],flip[N];
 12 void re(int x);
 13 inline void pushup(int x){
 14     int l=t[x][0],r=t[x][1];
 15     sum[x]=sum[l]+sum[r]+data[x];
 16     size[x]=size[l]+size[r]+1;
 17     mxl[x]=max(mxl[l],sum[l]+data[x]+max(mxl[r],0));
 18     mxr[x]=max(mxr[r],sum[r]+data[x]+max(mxr[l],0));
 19     mxm[x]=max(mxm[l],mxm[r]); 
 20     mxm[x]=max(mxm[x],max(mxr[l],0)+data[x]+max(mxl[r],0));
 21 }
 22 inline void pushdown(int x){
 23     int l=t[x][0],r=t[x][1];
 24     if(flip[x]){
 25         flip[x]=0;
 26         swap(t[x][0],t[x][1]);
 27         if(l){
 28             flip[l]^=1;
 29             swap(mxl[l],mxr[l]);
 30         }
 31         if(r){
 32             flip[r]^=1;
 33             swap(mxl[r],mxr[r]);
 34         }
 35     }
 36     if(same[x]!=-INF){
 37         if(l){
 38             same[l]=data[l]=same[x];
 39             sum[l]=same[l]*size[l];
 40             mxl[l]=mxr[l]=mxm[l]=max(data[l],sum[l]);
 41         }
 42         if(r){
 43             same[r]=data[r]=same[x];
 44             sum[r]=same[r]*size[r];
 45             mxl[r]=mxr[r]=mxm[r]=max(data[r],sum[r]);
 46         }
 47         same[x]=-INF;
 48     }
 49 }
 50 void Rotate(int x,int w){
 51     int y=fa[x],z=fa[y];
 52     pushdown(y);
 53     t[y][!w]=t[x][w];
 54     fa[t[x][w]]=y;
 55     fa[x]=z;
 56     t[z][t[z][1]==y]=x;
 57     t[x][w]=y;
 58     fa[y]=x;
 59     pushup(y);
 60 }
 61 void Splay(int x,int y){
 62     if(x!=y){
 63         pushdown(x);
 64         while(fa[x]!=y){
 65             if(t[fa[x]][0]==x)
 66                 Rotate(x,1);
 67             else
 68                 Rotate(x,0);
 69         }
 70         pushup(x);
 71         if(!y)root=x;
 72     }
 73     
 74 }
 75 void newnode(int &x,int y,int v){
 76     if(top>0)
 77         x=st[top--];
 78     else
 79         x=++id;
 80     flip[x]=t[x][0]=t[x][1]=0;
 81     mxl[x]=mxr[x]=mxm[x]=sum[x]=data[x]=v;
 82     same[x]=-INF;
 83     fa[x]=y;
 84     size[x]=1;
 85 }
 86 void build(int &x,int y,int l,int r){
 87     if(l<=r){
 88         int mid=(l+r)>>1;
 89         newnode(x,y,a[mid]);
 90         build(t[x][0],x,l,mid-1);
 91         build(t[x][1],x,mid+1,r);
 92         pushup(x);
 93     }
 94 }
 95 void init(int n){
 96     top=root=id=0;
 97     t[0][0]=t[0][1]=fa[0]=sum[0]=size[0]=data[0]=flip[0]=0;
 98     same[0]=mxl[0]=mxr[0]=mxm[0]=-INF;
 99     newnode(root,0,-INF);
100     newnode(t[1][1],1,-INF);
101     build(t[2][0],2,1,n);
102     pushup(2);
103     pushup(1);
104 }
105 int Select(int k){
106     pushdown(root);
107     int x=root;k++;
108     for(;size[t[x][0]]+1!=k;){
109         if(size[t[x][0]]+1>k)
110             x=t[x][0];
111         else
112             k-=size[t[x][0]]+1,x=t[x][1];
113         pushdown(x); 
114     }
115     return x;
116 }
117 void Insert(int c,int n){
118     for(int i=1;i<=n;i++){
119         scanf("%d",&a[i]);
120     }
121     int cc=Select(c+1);
122     c=Select(c);
123     Splay(c,0);
124     Splay(cc,c);
125     build(t[cc][0],cc,1,n);
126     pushup(cc);
127     pushup(c);
128 }
129 void recall(int x){
130     if(x){
131         st[++top]=x;
132         recall(t[x][0]);
133         recall(t[x][1]);
134     }
135 }
136 void Delete(int l,int r){
137     r=Select(r+1);
138     l=Select(l-1);
139     Splay(l,0);
140     Splay(r,l);
141     recall(t[r][0]);
142     t[r][0]=0;
143     pushup(r);
144     pushup(l);
145 }
146 void Flip(int l,int r){
147     r=Select(r+1);
148     l=Select(l-1);
149     Splay(l,0);
150     Splay(r,l);
151     flip[t[r][0]]^=1;
152     swap(mxl[t[r][0]],mxr[t[r][0]]);
153 }
154 void Same(int l,int r,int v){
155     r=Select(r+1);
156     l=Select(l-1);
157     Splay(l,0);
158     Splay(r,l);
159     int x=t[r][0];
160     same[x]=data[x]=v;
161     sum[x]=data[x]*size[x];
162     mxl[x]=mxr[x]=mxm[x]=max(v,sum[x]);
163     pushup(r);
164     pushup(l);
165 } 
166 int Sum(int l,int r){
167     r=Select(r+1);
168     l=Select(l-1);
169     Splay(l,0);
170     Splay(r,l);
171     return sum[t[r][0]];
172 }
173 int Max(int l,int r){
174     l=Select(l-1),r=Select(r+1);
175     Splay(l,0),Splay(r,l);
176     return mxm[t[r][0]];
177 }
178 void de(){
179     for(int i=1;i<=id;i++){
180         printf("%d %d %d %d %d++
",i,t[i][0],t[i][1],sum[i],mxm[i]);
181     }
182 }
183 void re(int x){
184     if(x){
185         re(t[x][0]);
186         printf("%d ",data[x]);
187         re(t[x][1]);
188     }
189 }
190 int main(){
191     int n,m,i,p,cnt,v;
192     char op[20];
193     while(scanf("%d%d",&n,&m)!=EOF){
194         for(i=1;i<=n;i++)    scanf("%d",&a[i]);
195         init(n);
196         //de();
197         while(m--){
198             scanf("%s",op);
199             if(!strcmp(op,"GET-SUM")){
200                 scanf("%d%d",&p,&cnt);
201                 printf("%d
",Sum(p,p+cnt-1));
202             }
203             if(!strcmp(op,"MAX-SUM")){
204                 printf("%d
",Max(1,size[root]-2));
205             }
206             if(!strcmp(op,"INSERT")){
207                 scanf("%d%d",&p,&cnt);
208                 Insert(p,cnt);
209             }
210             if(!strcmp(op,"DELETE")){
211                 scanf("%d%d",&p,&cnt);
212                 Delete(p,p+cnt-1);
213             }
214             if(!strcmp(op,"MAKE-SAME")){
215                 scanf("%d%d%d",&p,&cnt,&v);
216                 Same(p,p+cnt-1,v);
217             }
218             if(!strcmp(op,"REVERSE")){
219                 scanf("%d%d",&p,&cnt);
220                 Flip(p,p+cnt-1);
221             }
222         }
223     }
224     return 0;
225 }
226 /*
227 9 8
228 
229 2 -6 3 5 1 -5 -3 6 3
230 
231 GET-SUM 5 4
232 
233 MAX-SUM
234 
235 INSERT 8 3 -5 7 2
236 
237 DELETE 12 1
238 
239 MAKE-SAME 3 3 2
240 
241 REVERSE 3 6
242 
243 GET-SUM 5 4
244 
245 MAX-SUM
246 */
原文地址:https://www.cnblogs.com/L-King/p/5705193.html