NOI2005维修数列(splay)

题目描述:

Description

请写一个程序,要求维护一个数列,支持以下 6 种操作:
请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格

Input

输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

Output

对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

Sample Input

9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM

Sample Output

-1
10
1
10

 

解题思路:

听说出这道题时还没有splay,所以当时是块状链表题。

6种操作:

1.插入:

常规操作,将子树建好再把前驱后继中间空出来栽上,pushup两遍愈合即可。

PS:可以用建树时的build函数适配数组

2.删除:

将整棵树像挤痘痘一样挤出来扔掉。

PS:空间开不下,需要回收废树,不要将树分解,那样浪费时间,开一个栈,将废树压入,开新点时弹出一棵树,推入左右子树,根节点格式化输出即可。

3.修改:

常规操作,只不过用bool做懒惰标记主要是我怕它区间赋0

4.翻转:

文艺平衡树模板。

PS:pushdown时若有3的bool型标记就可以清除4的标记了。

5.求和:

维护一个sum

6.最大值:

类似vijos小白逛公园维护左连续最大值,右连续最大值,中间连续最大值即可。

PS:把0号节点的中间连续最大值赋为-,防止ans<0

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define lll tr[spc].ch[0]
  5 #define rrr tr[spc].ch[1]
  6 #define ls ch[0]
  7 #define rs ch[1]
  8 const int N=6000001;
  9 struct trnt{
 10     int ch[2];
 11     int fa;
 12     bool onmi;
 13     int lzt;
 14     int val;
 15     int sum;
 16     int wgt;
 17     int lmx,rmx,mmx;
 18     int chd;
 19 }tr[N];
 20 trnt stdtr;
 21 int n,m;
 22 int lne[N];
 23 int bin[N];
 24 int top=0;
 25 int root;
 26 int siz;
 27 char cmd[100];
 28 int ins[N];
 29 int org,fin;
 30 void destory(int &spc)
 31 {
 32     bin[++top]=spc;
 33     spc=0;
 34     return ;
 35 }
 36 int translate(void)
 37 {
 38     int tmp=(int)(cmd[2]);
 39     if(tmp=='S')
 40         return 1;
 41     if(tmp=='L')
 42         return 2;
 43     if(tmp=='K')
 44         return 3;
 45     if(tmp=='V')
 46         return 4;
 47     if(tmp=='T')
 48         return 5;
 49     if(tmp=='X')
 50         return 6;
 51        return 0;
 52 }
 53 bool whc(int spc)
 54 {
 55     return tr[tr[spc].fa].rs==spc;
 56 }
 57 void pushup(int spc)
 58 {
 59     tr[spc].sum=tr[lll].sum+tr[rrr].sum+tr[spc].val;
 60     tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+1;
 61     tr[spc].lmx=std::max(tr[lll].lmx,tr[lll].sum+tr[spc].val+tr[rrr].lmx);
 62     tr[spc].rmx=std::max(tr[rrr].rmx,tr[rrr].sum+tr[spc].val+tr[lll].rmx);
 63     tr[spc].mmx=std::max(tr[spc].val+tr[lll].rmx+tr[rrr].lmx,std::max(tr[lll].mmx,tr[rrr].mmx));
 64     return ;
 65 }
 66 int apply()
 67 {
 68     if(top)
 69     {
 70         int spc=bin[top--];
 71         if(lll)
 72             bin[++top]=lll;
 73         if(rrr)
 74             bin[++top]=rrr;
 75         return spc;
 76     }
 77     return ++siz;
 78 }
 79 void address(int &spc)
 80 {
 81     spc=apply();
 82     tr[spc]=stdtr;
 83     return ;
 84 }
 85 void new_point(int &spc,int mid,int *a,int f)
 86 {
 87     address(spc);
 88     tr[spc].fa=f;
 89     tr[spc].val=a[mid];
 90     return ;
 91 }
 92 void din(int spc,int k)
 93 {
 94     if(!spc)
 95         return ;
 96     tr[spc].onmi=true;
 97     tr[spc].lzt=k;
 98     tr[spc].val=k;
 99     tr[spc].sum=tr[spc].wgt*k;
100     tr[spc].mmx=(k>0)?tr[spc].sum:k;
101     tr[spc].lmx=tr[spc].rmx=(k>0)?tr[spc].sum:0;
102     return ;
103 }
104 void ovt(int spc)
105 {
106     if(!spc)
107         return ;
108     tr[spc].chd^=1;
109     std::swap(lll,rrr);
110     std::swap(tr[spc].lmx,tr[spc].rmx);
111     return ;
112 }
113 void pushdown(int spc)
114 {
115     if(tr[spc].onmi)
116     {
117         din(lll,tr[spc].lzt);
118         din(rrr,tr[spc].lzt);
119         tr[spc].lzt=0;
120         tr[spc].chd=0;
121         tr[spc].onmi=false;
122     }
123     if(tr[spc].chd)
124     {
125         ovt(lll);
126         ovt(rrr);
127         tr[spc].chd=0;
128     }
129     return ;
130 }
131 void rotate(int spc)
132 {
133     int f=tr[spc].fa;
134     bool k=whc(spc);
135     tr[f].ch[k]=tr[spc].ch[!k];
136     tr[spc].ch[!k]=f;
137     tr[tr[f].fa].ch[whc(f)]=spc;
138     tr[spc].fa=tr[f].fa;
139     tr[f].fa=spc;
140     tr[tr[f].ch[k]].fa=f;
141     pushup(f);
142     pushup(spc);
143     return ;
144 }
145 void splay(int spc,int f)
146 {
147     while(tr[spc].fa!=f)
148     {
149         int ft=tr[spc].fa;
150         if(tr[ft].fa==f)
151         {
152             rotate(spc);
153             break;
154         }
155         if(whc(spc)^whc(ft))
156             rotate(spc);
157         else
158             rotate(ft);
159         rotate(spc);
160     }
161     if(!f)
162         root=spc;
163     return ;
164 }
165 void build(int l,int r,int &spc,int f,int *a)
166 {
167     if(l>r)
168         return ;
169     int mid=(l+r)>>1;
170     new_point(spc,mid,a,f);
171     if(l==r)
172     {
173         tr[spc].lmx=tr[spc].rmx=(a[mid]>0)?a[mid]:0;
174         tr[spc].mmx=a[mid];
175         tr[spc].wgt=1;
176         tr[spc].sum=a[mid];
177         if(l==0)
178             org=spc;
179            if(l==n+1)
180                fin=spc;
181     }
182     build(l,mid-1,lll,spc,a);
183     build(mid+1,r,rrr,spc,a);
184     pushup(spc);
185     if(l==r)
186         tr[spc].mmx=tr[spc].val;
187     return ;
188 }
189 int place(int spc,int rnk)
190 {
191     pushdown(spc);
192     if(tr[lll].wgt>=rnk)
193         return place(lll,rnk);
194     if(tr[lll].wgt+1==rnk)
195         return spc;
196     return place(rrr,rnk-tr[lll].wgt-1);
197 }
198 int main()
199 {
200     scanf("%d%d",&n,&m);
201     for(int i=1;i<=n;i++)
202         scanf("%d",&lne[i]);
203     build(0,n+1,root,0,lne);
204     tr[0].mmx=-0x3f3f3f3f;
205     while(m--)
206     {
207         scanf("%s",cmd);
208         int opr=translate();
209         if(opr==1)
210         {
211             int tmproot;
212             int pos,tot;
213             scanf("%d%d",&pos,&tot);
214             for(int i=1;i<=tot;i++)
215                 scanf("%d",&ins[i]);
216             build(1,tot,tmproot,0,ins);
217             splay(place(root,pos+1),0);
218             splay(place(root,pos+2),root);
219             tr[tr[root].rs].ls=tmproot;
220             tr[tmproot].fa=tr[root].rs;
221             pushup(tr[root].rs);
222             pushup(root);
223         }else if(opr==2)
224         {
225             int pos,tot;
226             scanf("%d%d",&pos,&tot);
227             splay(place(root,pos),0);
228             splay(place(root,pos+tot+1),root);
229             destory(tr[tr[root].rs].ls);
230             pushup(tr[root].rs);
231             pushup(root);
232         }else if(opr==3)
233         {
234             int pos,tot,c;
235             scanf("%d%d%d",&pos,&tot,&c);
236             splay(place(root,pos),0);
237             splay(place(root,pos+tot+1),root);
238             pushdown(root);
239             pushdown(tr[root].rs);
240             int spc=tr[tr[root].rs].ls;
241             din(spc,c);
242             pushup(tr[root].rs);
243             pushup(root);
244         }else if(opr==4)
245         {
246             int pos,tot;
247             scanf("%d%d",&pos,&tot);
248             splay(place(root,pos),0);
249             splay(place(root,pos+tot+1),root);
250             pushdown(root);
251             pushdown(tr[root].rs);
252             int spc=tr[tr[root].rs].ls;
253             ovt(spc);
254             pushup(tr[root].rs);
255             pushup(root);
256         }else if(opr==5)
257         {
258             int pos,tot;
259             scanf("%d%d",&pos,&tot);
260             splay(place(root,pos),0);
261             splay(place(root,pos+tot+1),root);
262             int spc=tr[tr[root].rs].ls;
263             printf("%d
",tr[spc].sum);
264         }else{
265             splay(place(root,1),0);
266             splay(place(root,tr[root].wgt),root);
267             printf("%d
",tr[tr[tr[root].rs].ls].mmx);
268         }
269     }
270     return 0;
271 }

原文地址:https://www.cnblogs.com/blog-Dr-J/p/9600970.html