维修数列 Splay(这可能是我写过最麻烦的题之一了。。。用平衡树维护dp。。。丧心病狂啊。。。。)

题目来源BZOJ1500

这题的思路:

1、这题的话,稍微会splay的人,一般前面四个都不是问题。。主要是最后的一个,要你在修改的同时要维护好最大字段和。。。

2、最大字段和其实就是区间合并。具体操作可以看POJ2750,这是这道题的简化版本。

3、然后这题就是三个区间合并嘛。。。慢慢讨论就好了。。。这题写了我一天的时间。。从吃完午饭一直写到了晚上8点才AC。。。

直接贴代码吧。。这题是我为了学LCT,所以想做做Splay的题先熟悉一下Splay。。。结果选了这个BOSS题。。。心理阴影。。。。

我觉得我pushup那段写的挺清楚的23333   思路可以看我的pushup和pushdown函数的代码,应该挺好懂的

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<stack>
  5  
  6 using namespace std;
  7  
  8 const int N=500005,INF=0x3f3f3f3f;
  9  
 10 struct Splay_Tree
 11 {
 12     struct Node
 13     {
 14         int val,sum,cover,Size,son[2],mxl,mxr,mx;
 15         bool rev,cov;
 16         void init(int _val)
 17         {
 18             val=sum=mxl=mxr=mx=_val;
 19             Size=1;
 20             rev=cov=cover=son[0]=son[1]=0;
 21         }
 22     } T[N];
 23     stack<int>mem;
 24     int fa[N],root,tot;
 25  
 26     void pushDown(int x)///下放标记(序列操作)
 27     {
 28         if(x==0)return ;
 29         if(T[x].cov)
 30         {
 31             if(T[x].son[0])
 32             {
 33                 T[T[x].son[0]].cov=1;
 34                 T[T[x].son[0]].cover=T[T[x].son[0]].val=T[x].cover;
 35                 T[T[x].son[0]].sum=T[x].cover*T[T[x].son[0]].Size;
 36                 T[T[x].son[0]].rev=0;
 37                 if(T[x].cover>=0)
 38                     T[T[x].son[0]].mx=T[T[x].son[0]].mxl=T[T[x].son[0]].mxr=T[x].cover*T[T[x].son[0]].Size;
 39                 else
 40                     T[T[x].son[0]].mx=T[T[x].son[0]].mxl=T[T[x].son[0]].mxr=T[x].cover;
 41             }
 42             if(T[x].son[1])
 43             {
 44                 T[T[x].son[1]].cov=1;
 45                 T[T[x].son[1]].cover=T[T[x].son[1]].val=T[x].cover;
 46                 T[T[x].son[1]].sum=T[x].cover*T[T[x].son[1]].Size;
 47                 T[T[x].son[1]].rev=0;
 48                 if(T[x].cover>=0)
 49                     T[T[x].son[1]].mx=T[T[x].son[1]].mxl=T[T[x].son[1]].mxr=T[x].cover*T[T[x].son[1]].Size;
 50                 else
 51                     T[T[x].son[1]].mx=T[T[x].son[1]].mxl=T[T[x].son[1]].mxr=T[x].cover;
 52             }
 53             T[x].cov=T[x].cover=T[x].rev=0;
 54         }
 55         if(T[x].rev)
 56         {
 57             if(T[x].son[0])
 58             {
 59                 T[T[x].son[0]].rev^=1;
 60                 swap(T[T[x].son[0]].mxl,T[T[x].son[0]].mxr);
 61             }
 62             if(T[x].son[1])
 63             {
 64                 T[T[x].son[1]].rev^=1;
 65                 swap(T[T[x].son[1]].mxl,T[T[x].son[1]].mxr);
 66             }
 67             swap(T[x].son[0],T[x].son[1]);
 68             T[x].rev=0;
 69         }
 70     }
 71  
 72     void pushUp(int x)///更新节点(序列操作)
 73     {
 74         T[x].Size=1;
 75         T[x].sum=T[x].val;
 76         if(T[x].son[0])
 77             T[x].sum+=T[T[x].son[0]].sum,T[x].Size+=T[T[x].son[0]].Size;
 78         if(T[x].son[1])
 79             T[x].sum+=T[T[x].son[1]].sum,T[x].Size+=T[T[x].son[1]].Size;
 80  
 81         if(T[x].son[0]&&T[x].son[1])
 82         {
 83             T[x].mx=T[x].val;
 84             T[x].mx=max(T[x].mx,T[T[x].son[0]].mx);
 85             T[x].mx=max(T[x].mx,T[T[x].son[1]].mx);
 86             T[x].mx=max(T[x].mx,T[T[x].son[0]].mxr+T[x].val+T[T[x].son[1]].mxl);
 87             T[x].mx=max(T[x].mx,T[x].val+T[T[x].son[0]].mxr);
 88             T[x].mx=max(T[x].mx,T[x].val+T[T[x].son[1]].mxl);
 89  
 90             T[x].mxl=T[T[x].son[0]].mxl;
 91             T[x].mxl=max(T[x].mxl,T[T[x].son[0]].sum+T[x].val);
 92             T[x].mxl=max(T[x].mxl,T[T[x].son[0]].sum+T[x].val+T[T[x].son[1]].mxl);
 93  
 94             T[x].mxr=T[T[x].son[1]].mxr;
 95             T[x].mxr=max(T[x].mxr,T[T[x].son[1]].sum+T[x].val);
 96             T[x].mxr=max(T[x].mxr,T[T[x].son[1]].sum+T[x].val+T[T[x].son[0]].mxr);
 97         }
 98         else if(T[x].son[0]&&!T[x].son[1])
 99         {
100             T[x].mx=max(T[T[x].son[0]].mxr+T[x].val,T[T[x].son[0]].mx);
101  
102             T[x].mx=max(T[x].mx,T[x].val);
103  
104             T[x].mxl=max(T[T[x].son[0]].mxl,T[T[x].son[0]].sum+T[x].val);
105  
106             T[x].mxr=max(T[x].val,T[x].val+T[T[x].son[0]].mxr);
107         }
108         else if(!T[x].son[0]&&T[x].son[1])
109         {
110             T[x].mx=max(T[T[x].son[1]].mxl+T[x].val,T[T[x].son[1]].mx);
111  
112             T[x].mx=max(T[x].mx,T[x].val);
113  
114             T[x].mxl=max(T[x].val,T[x].val+T[T[x].son[1]].mxl);
115  
116             T[x].mxr=max(T[T[x].son[1]].mxr,T[T[x].son[1]].sum+T[x].val);
117         }
118         else T[x].mxl=T[x].mxr=T[x].mx=T[x].val;
119  
120     }
121  
122     /*inline void up(int x)///更新节点(普通平衡树操作)
123     {
124         T[x].Size=1;
125         if(T[x].son[0])
126             T[x].Size+=T[T[x].son[0]].Size;
127         if(T[x].son[1])
128             T[x].Size+=T[T[x].son[1]].Size;
129     }*/
130  
131     void Rotate(int x,int kind)///旋转,有左旋右旋(反正配合splay用就好了233)
132     {
133         int y=fa[x],z=fa[y];
134         T[y].son[!kind]=T[x].son[kind],fa[T[x].son[kind]]=y;
135         T[x].son[kind]=y,fa[y]=x;
136         T[z].son[T[z].son[1]==y]=x,fa[x]=z;
137         pushUp(y);
138     }
139  
140     void Splay(int x,int goal)///把下标为x的元素旋转到目标的儿子节点
141     {
142         if(x==goal)return ;
143         while(fa[x]!=goal)
144         {
145             int y=fa[x],z=fa[y];
146             pushDown(z),pushDown(y),pushDown(x);
147             int rx=T[y].son[0]==x,ry=T[z].son[0]==y;
148             if(z==goal)Rotate(x,rx);
149             else
150             {
151                 if(rx==ry)Rotate(y,ry);
152                 else Rotate(x,rx);
153                 Rotate(x,ry);
154             }
155         }
156         pushUp(x);
157         if(goal==0)root=x;
158     }
159  
160     int Select(int pos)///查找第k小元素
161     {
162         pos--;
163         int u=root;
164         pushDown(u);
165         while(T[T[u].son[0]].Size!=pos)
166         {
167             if(pos<T[T[u].son[0]].Size)u=T[u].son[0];
168             else
169             {
170                 pos-=T[T[u].son[0]].Size+1;
171                 u=T[u].son[1];
172             }
173             pushDown(u);
174         }
175         return u;
176     }
177  
178  
179     void Reverse(int L,int R)///序列操作的区间翻转
180     {
181         if(L>R)return ;
182         int u=Select(L-1),v=Select(R+1);
183         Splay(u,0);
184         Splay(v,u);
185         T[T[v].son[0]].rev^=1;
186         swap(T[T[v].son[0]].mxl,T[T[v].son[0]].mxr);
187         pushDown(T[v].son[0]);
188         update(T[v].son[0]);
189     }
190  
191     void Cover(int L,int R,int Val)///序列操作的区间翻转
192     {
193         if(L>R)return ;
194         int u=Select(L-1),v=Select(R+1);
195         Splay(u,0);
196         Splay(v,u);
197         T[T[v].son[0]].cov=1;
198         T[T[v].son[0]].cover=T[T[v].son[0]].val=Val;
199         pushDown(T[v].son[0]);
200         update(T[v].son[0]);
201     }
202  
203     int build(int L,int R,int *a)///区间操作建树
204     {
205         if(L>R)return 0;
206         int mid=(L+R)>>1,sL,sR;
207         int loc=mem.top();mem.pop();
208         T[loc].init(a[mid]);
209         if(L==R)return loc;
210         T[loc].son[0]=sL=build(L,mid-1,a);
211         T[loc].son[1]=sR=build(mid+1,R,a);
212         fa[sL]=fa[sR]=loc;
213         pushUp(loc);
214         return loc;
215     }
216  
217     void init(int n,int *a)///区间操作,输入n个元素建树
218     {
219         T[0].init(INF);
220         for(int i=500001;i>=1;i--)
221             mem.push(i);
222         root=build(1,n,a),fa[root]=0;
223         fa[0]=0,T[0].son[1]=root,T[0].Size=0;
224     }
225  
226     void Insert(int pos,int n,int *a)
227     {
228         if(n==0)return ;
229         int u=Select(pos-1),v=Select(pos);
230         Splay(u,0);
231         Splay(v,u);
232         fa[T[v].son[0]=build(1,n,a)]=v;
233         update(T[v].son[0]);
234     }
235  
236     void Delete(int L,int R)
237     {
238         if(L>R)return ;
239         int u=Select(L-1),v=Select(R+1);
240         Splay(u,0);
241         Splay(v,u);
242         Free(T[v].son[0]);
243         T[v].son[0]=0;
244         update(v);
245     }
246  
247     int Get_sum(int L,int R)
248     {
249         if(L>R)return 0;
250         int u=Select(L-1),v=Select(R+1);
251         Splay(u,0);
252         Splay(v,u);
253         if(T[v].son[0])
254             return T[T[v].son[0]].sum;
255         else return 0;
256     }
257  
258     int Get_max(int L,int R)
259     {
260         if(L>R)return 0;
261         int u=Select(L-1),v=Select(R+1);
262         Splay(u,0);
263         Splay(v,u);
264         if(T[v].son[0])
265             return T[T[v].son[0]].mx;
266         else return 0;
267     }
268  
269     void Free(int x)
270     {
271         if(x==0)return ;
272         Free(T[x].son[0]);
273         mem.push(x);
274         Free(T[x].son[1]);
275     }
276  
277     /*void Insert(int &t,int val,int par=0)///普通平衡树,往某个地方的下面插入元素,一般是插入根节点
278     {
279         if(t==0)
280         {
281             t=++tot;
282             T[t].init(val);
283             fa[t]=par;
284             Splay(tot,0);
285         }
286         else
287         {
288             int cur=t;
289             if(val<T[t].val)Insert(T[t].son[0],val,cur);
290             //else if(val==T[t].val)return ;
291             else Insert(T[t].son[1],val,cur);
292             up(cur);
293         }
294     }*/
295  
296     /*int find(int t,int v)///普通平衡树查找值为v的元素
297     {
298         if(t==0)return 0;
299         else if(T[t].val==v)
300         {
301             Splay(t,0);
302             return t;
303         }
304         else if(v<T[t].val)return find(T[t].son[0],v);
305         else return find(T[t].son[1],v);
306     }*/
307  
308     ///删除根节点元素
309     /*void Delete()
310     {
311         if(!T[root].son[0])
312         {
313             fa[T[root].son[1]]=0;
314             root=T[root].son[1];
315         }
316         else
317         {
318             int cur=T[root].son[0];
319             while(T[cur].son[1])cur=T[cur].son[1];
320             Splay(cur,root);
321             T[cur].son[1]=T[root].son[1];
322             root=cur,fa[cur]=0,fa[T[root].son[1]]=root;
323             up(root);
324         }
325     }*/
326  
327     int size()
328     {
329         return T[root].Size;
330     }
331  
332     ///从t开始找值为v的前驱,返回值
333     int pred(int t,int v)
334     {
335         if(t==0)return v;
336         else
337         {
338             if(v<=T[t].val)return pred(T[t].son[0],v);
339             else
340             {
341                 int ans=pred(T[t].son[1],v);
342                 if(ans==v)
343                     ans=T[t].val,Splay(t,0);
344                 return ans;
345             }
346         }
347     }
348     ///查找下标t节点的前驱返回下标
349     int pred(int t)
350     {
351         Splay(t,0);
352         int u=T[t].son[0];
353         if(u==0)return fa[t];
354         while(T[u].son[1])u=T[u].son[1];
355         return u;
356     }
357  
358     ///从t开始找值为v的后继,返回值
359     int succ(int t,int v)
360     {
361         if(t==0)return v;
362         else
363         {
364             if(v>=T[t].val)return succ(T[t].son[1],v);
365             else
366             {
367                 int ans=succ(T[t].son[0],v);
368                 if(ans==v)
369                     ans=T[t].val,Splay(t,0);
370                 return ans;
371             }
372         }
373     }
374  
375     ///查找下标t节点的后继返回下标
376     int succ(int t)
377     {
378         Splay(t,0);
379         int u=T[t].son[1];
380         if(u==0)return fa[t];
381         while(T[u].son[0])u=T[u].son[0];
382         return u;
383     }
384  
385     void Preorder( int t ){///输出成序列顺便检查是否有逻辑错误
386         if( !t ) return;
387         pushDown(t);
388         Preorder( T[t].son[0] );
389         if(T[t].son[0]&&fa[T[t].son[0]]!=t)
390             printf("!");
391         printf("%d " , T[t].val );
392         Preorder( T[t].son[1] );
393     }
394  
395     /*void init()///普通平衡树初始化
396     {
397         T[0].init(-INF);
398         tot=root=0;
399     }*/
400  
401     void update(int x)///更新下标为x的节点。。手动操作后调用
402     {
403         while(x!=0)
404         pushUp(x),x=fa[x];
405     }
406  
407 };
408  
409 Splay_Tree tree;
410  
411 int a[N];
412  
413 char str[22];
414  
415 int main()
416 {
417     int n,m;
418     scanf("%d%d",&n,&m);
419     for(int i=2;i<=n+1;i++)
420         scanf("%d",a+i);
421     tree.init(n+2,a);
422     int sum=n;
423     while(m--)
424     {
425         scanf("%s",str+1);
426         if(str[3]=='S')
427         {
428             int pos,tot;
429             scanf("%d%d",&pos,&tot);
430             pos++;
431             pos++;
432             sum+=tot;
433             for(int i=1;i<=tot;i++)
434                 scanf("%d",a+i);
435             tree.Insert(pos,tot,a);
436         }
437         else if(str[3]=='L')
438         {
439             int pos,tot;
440             scanf("%d%d",&pos,&tot);
441             pos++;
442             tree.Delete(pos,pos+tot-1);
443             sum-=tot;
444         }
445         else if(str[3]=='K')
446         {
447             int pos,tot,cov;
448             scanf("%d%d%d",&pos,&tot,&cov);
449             pos++;
450             tree.Cover(pos,pos+tot-1,cov);
451         }
452         else if(str[3]=='V')
453         {
454             int pos,tot;
455             scanf("%d%d",&pos,&tot);
456             pos++;
457             tree.Reverse(pos,pos+tot-1);
458         }
459         else if(str[3]=='T')
460         {
461             int pos,tot;
462             scanf("%d%d",&pos,&tot);
463             pos++;
464             printf("%d
",tree.Get_sum(pos,pos+tot-1));
465         }
466         if(str[3]=='X')
467         {
468             printf("%d
",tree.Get_max(2,tree.size()-1));
469         }
470     }
471     return 0;
472 }
473 
View Code
原文地址:https://www.cnblogs.com/xseventh/p/8585828.html