……妈妈我会写维修数列了!
一道十分恶心的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 }
话说这好像是17年A的第一道题……开门红,不错不错……
233333333