……妈妈我会写维修数列了!

我是萌萌的传送门

一道十分恶心的splay模板题,听说有无数神犇花了各种半天/一天才过……

说说我写这题的历程:

联赛之前

第一弹大概在10月份,写的是splay,因为对splay并不熟,把问题想复杂了,吓得没写完就弃坑了。

第二弹也是10月,这次抄了个fhq Treap模板,结果又W又T,调了一下午+一晚上没出来,弃疗……

第三弹大概是11月初,重新自己写了个splay,这次好歹能过第一个点,然而还是9个W,各种调不出来,调了几个小时之后怒而第三次弃疗。

联赛之后

第四弹,也就是今天,心血来潮想把这道心头大恨切掉,然后就开始写splay,稍微调了一会儿(半个多小时……?)就A了……卧槽怎么维修数列这么简单(装B

其实splay基本操作并不难,难点主要在附加信息的维护上,表示感觉自己弄出来的几种写法都是等价的,然而只有这个版本能过……

  1 /**************************************************************
  2     Problem: 1500
  3     User: hzoier
  4     Language: C++
  5     Result: Accepted
  6     Time:6048 ms
  7     Memory:41608 kb
  8 ****************************************************************/
  9  
 10 #include<cstdio>
 11 #include<cstring>
 12 #include<algorithm>
 13 #define dir(x) ((int)((x)==(x)->p->ch[1]))
 14 using namespace std;
 15 struct node{
 16     int data,size,sum,prefix,suffix,maxsum;
 17     bool rev,same;
 18     node *ch[2],*p;
 19     node(int d):data(d),size(1),sum(d),prefix(d),suffix(d),maxsum(d),rev(false),same(false){}
 20     void reverse(){
 21         if(data==-1000000)return;
 22         rev^=true;
 23         swap(prefix,suffix);
 24     }
 25     void makesame(int d){
 26         if(data==-1000000)return;
 27         data=d;
 28         sum=d*size;
 29         prefix=suffix=maxsum=max(sum,d);
 30         same=true;
 31     }
 32     void pushdown(){
 33         if(rev){
 34             ch[0]->reverse();
 35             ch[1]->reverse();
 36             swap(ch[0],ch[1]);
 37             rev=false;
 38         }
 39         if(same){
 40             ch[0]->makesame(data);
 41             ch[1]->makesame(data);
 42             same=false;
 43         }
 44     }
 45     void refresh(){
 46         size=ch[0]->size+ch[1]->size+1;
 47         sum=ch[0]->sum+ch[1]->sum+data;
 48         prefix=max(ch[0]->prefix,ch[0]->sum+data+max(ch[1]->prefix,0));
 49         suffix=max(ch[1]->suffix,ch[1]->sum+data+max(ch[0]->suffix,0));
 50         maxsum=max(max(ch[0]->maxsum,ch[1]->maxsum),max(ch[0]->suffix,0)+data+max(ch[1]->prefix,0));
 51     }
 52 }*null=new node(-1000000),*root=null;
 53 void insert(int,int);
 54 void erase(int,int);
 55 void makesame(int,int,int);
 56 void reverse(int,int);
 57 int getsum(int,int);
 58 int maxsum();
 59 node *build(int,int);
 60 void removetree(node*);
 61 node *kth(int);
 62 void splay(node*,node*);
 63 void rot(node*,int);
 64 int n,m,pos,cnt,d,a[5000010];
 65 char c[15];
 66 int main(){
 67     null->ch[0]=null->ch[1]=null->p=null;
 68     null->size=null->sum=0;
 69     scanf("%d%d",&n,&m);
 70     insert(0,n);//dfs(root);
 71     while(m--){
 72         scanf("%s",c);
 73         if(!strcmp(c,"INSERT")){
 74             scanf("%d%d",&pos,&cnt);
 75             insert(pos,cnt);
 76         }
 77         else if(!strcmp(c,"DELETE")){
 78             scanf("%d%d",&pos,&cnt);
 79             erase(pos,cnt);
 80         }
 81         else if(!strcmp(c,"MAKE-SAME")){
 82             scanf("%d%d%d",&pos,&cnt,&d);
 83             makesame(pos,cnt,d);
 84         }
 85         else if(!strcmp(c,"REVERSE")){
 86             scanf("%d%d",&pos,&cnt);
 87             reverse(pos,cnt);
 88         }
 89         else if(!strcmp(c,"GET-SUM")){
 90             scanf("%d%d",&pos,&cnt);
 91             printf("%d\n",getsum(pos,cnt));
 92         }
 93         else if(!strcmp(c,"MAX-SUM"))printf("%d\n",maxsum());
 94     }
 95     return 0;
 96 }
 97 node *newnode(int d){
 98     node *x=new node(d);
 99     x->ch[0]=x->ch[1]=x->p=null;
100     return x;
101 }
102 void insert(int pos,int cnt){
103     for(int i=1;i<=cnt;i++)scanf("%d",&a[i]);
104     node *x=build(1,cnt);
105     if(root==null){
106         root=x;
107         return;
108     }
109     if(!pos){
110         splay(kth(1),null);
111         root->ch[0]=x;
112         x->p=root;
113         root->refresh();
114     }
115     else if(pos==root->size){
116         splay(kth(root->size),null);
117         root->ch[1]=x;
118         x->p=root;
119         root->refresh();
120     }
121     else{
122         splay(kth(pos),null);
123         splay(kth(pos+1),root);
124         root->ch[1]->ch[0]=x;
125         x->p=root->ch[1];
126         root->ch[1]->refresh();
127         root->refresh();
128     }
129 }
130 void erase(int pos,int cnt){
131     if(cnt==root->size){
132         removetree(root);
133         root=null;
134         return;
135     }
136     if(pos==1){
137         splay(kth(cnt+1),null);
138         removetree(root->ch[0]);
139         root->ch[0]=null;
140         root->refresh();
141     }
142     else if(pos+cnt-1==root->size){
143         splay(kth(pos-1),null);
144         removetree(root->ch[1]);
145         root->ch[1]=null;
146         root->refresh();
147     }
148     else{
149         splay(kth(pos-1),null);
150         splay(kth(pos+cnt),root);
151         removetree(root->ch[1]->ch[0]);
152         root->ch[1]->ch[0]=null;
153         root->ch[1]->refresh();
154         root->refresh();
155     }
156 }
157 void makesame(int pos,int cnt,int d){
158     if(cnt==root->size)root->makesame(d);
159     else if(pos==1){
160         splay(kth(cnt+1),null);
161         root->ch[0]->makesame(d);
162         root->refresh();
163     }
164     else if(pos+cnt-1==root->size){
165         splay(kth(pos-1),null);
166         root->ch[1]->makesame(d);
167         root->refresh();
168     }
169     else{
170         splay(kth(pos-1),null);
171         splay(kth(pos+cnt),root);
172         root->ch[1]->ch[0]->makesame(d);
173         root->ch[1]->refresh();
174         root->refresh();
175     }
176 }
177 void reverse(int pos,int cnt){
178     if(cnt==root->size)root->reverse();
179     else if(pos==1){
180         splay(kth(cnt+1),null);
181         root->ch[0]->reverse();
182         root->refresh();
183     }
184     else if(pos+cnt-1==root->size){
185         splay(kth(pos-1),null);
186         root->ch[1]->reverse();
187         root->refresh();
188     }
189     else{
190         splay(kth(pos-1),null);
191         splay(kth(pos+cnt),root);
192         root->ch[1]->ch[0]->reverse();
193         root->ch[1]->refresh();
194         root->refresh();
195     }
196 }
197 int getsum(int pos,int cnt){
198     if(!cnt)return 0;
199     if(cnt==root->size)return root->sum;
200     else if(pos==1){
201         splay(kth(cnt+1),null);
202         return root->ch[0]->sum;
203     }
204     else if(pos+cnt-1==root->size){
205         splay(kth(pos-1),null);
206         return root->ch[1]->sum;
207     }
208     else{
209         splay(kth(pos-1),null);
210         splay(kth(pos+cnt),root);
211         return root->ch[1]->ch[0]->sum;
212     }
213 }
214 int maxsum(){
215     if(root==null)return 0;
216     root->pushdown();
217     return root->maxsum;
218 }
219 node *build(int l,int r){
220     if(l>r)return null;
221     int mid=(l+r)>>1;
222     node *x=newnode(a[mid]);
223     if((x->ch[0]=build(l,mid-1))!=null)x->ch[0]->p=x;
224     if((x->ch[1]=build(mid+1,r))!=null)x->ch[1]->p=x;
225     x->refresh();
226     return x;
227 }
228 void removetree(node *x){
229     if(x==null)return;
230     removetree(x->ch[0]);
231     removetree(x->ch[1]);
232     delete x;
233 }
234 node *kth(int k){
235     node *rt=root;
236     int d;
237     while(rt){
238         rt->pushdown();
239         if(k==rt->ch[0]->size+1)return rt;
240         if((d=k>rt->ch[0]->size))k-=rt->ch[0]->size+1;
241         rt=rt->ch[d];
242     }
243     return null;
244 }
245 void splay(node *x,node *tar){
246     while(x->p!=tar){
247         if(x->p->p==tar){
248             rot(x->p,dir(x)^1);
249             break;
250         }
251         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
252         else rot(x->p,dir(x)^1);
253         rot(x->p,dir(x)^1);
254     }
255 }
256 void rot(node *x,int d){
257     node *y=x->ch[d^1];
258     x->ch[d^1]=y->ch[d];
259     if(y->ch[d]!=null)y->ch[d]->p=x;
260     y->p=x->p;
261     if(x->p!=null)x->p->ch[dir(x)]=y;
262     else root=y;
263     y->ch[d]=x;
264     x->p=y;
265     x->refresh();
266     y->refresh();
267 }
View Code

话说这好像是17年A的第一道题……开门红,不错不错……

posted @ 2017-01-01 16:40  AntiLeaf  阅读(181)  评论(0编辑  收藏  举报