维修数列代码及简易题解
总体方案:将左右端点分别转到根和根的右儿子,将目标序列挤到以根的右儿子的左儿子为根的子树中,然后进行一系列骚操作即可
建树:用类似线段树的方法建树,递归即可,注意加两个边界点
插入:读入这些数,用建树函数建出一颗子树,接到根的右儿子的左儿子处
删除:递归删除即可
修改:在根的右儿子的左儿子处打懒标记,像线段树一样
翻转:和文艺平衡树一样,打懒标记
求和:输出根的右儿子的左儿子的sum
求最大子序列:利用线段树合并的思想即可。
此题细节极多,具体见代码
鄙人为了能过,进行了大量的特判,再加上鄙人不想写内存回收,用了作死指针,码风奇丑无比,众巨佬们勿喷。
1 #include<cstdio> 2 struct node 3 { 4 int val,sum,set,laz,siz,lm,rm,maxv,setv,vod; 5 node *fa,*son[2]; 6 node() 7 { 8 fa=NULL; 9 son[0]=son[1]=NULL; 10 val=sum=set=laz=siz=setv=vod=0; 11 lm=rm=maxv=-(1<<30); 12 } 13 }; 14 node *root,*fail; 15 int n,m,v[500100],n0,p0,p1,c; 16 char op[50]; 17 int max(int a,int b){return a>b?a:b;} 18 void pushup(node *nc) 19 { 20 nc->siz=nc->son[0]->siz+nc->son[1]->siz+1; 21 nc->sum=nc->son[0]->sum+nc->son[1]->sum+nc->val; 22 if((!nc->son[0]->siz&&!nc->son[1]->siz)||(nc->son[0]->vod&&nc->son[1]->vod&&nc->son[0]->siz==1&&nc->son[1]->siz==1)||(!nc->son[0]->siz&&nc->son[1]->vod&&nc->son[1]->siz==1)||(!nc->son[1]->siz&&nc->son[0]->vod&&nc->son[0]->siz==1)) 23 { 24 nc->lm=nc->val; 25 nc->rm=nc->val; 26 nc->maxv=nc->val; 27 return; 28 } 29 if(!nc->son[0]->siz||(nc->son[0]->vod&&nc->son[0]->siz==1)) 30 { 31 if(!nc->vod) 32 { 33 nc->maxv=max(nc->val+nc->son[1]->lm,max(nc->son[1]->maxv,nc->val)); 34 nc->lm=max(nc->val+nc->son[1]->lm,nc->val); 35 } 36 else 37 { 38 nc->lm=nc->son[1]->lm; 39 nc->maxv=max(nc->val+nc->son[1]->lm,nc->son[1]->maxv); 40 } 41 nc->rm=max(nc->son[1]->rm,nc->val+nc->son[1]->sum); 42 return; 43 } 44 if(!nc->son[1]->siz||(nc->son[1]->vod&&nc->son[1]->siz==1)) 45 { 46 nc->lm=max(nc->val+nc->son[0]->sum,nc->son[0]->lm); 47 if(!nc->vod) 48 { 49 nc->rm=max(nc->son[0]->rm+nc->val,nc->val); 50 nc->maxv=max(nc->val+nc->son[0]->rm,max(nc->son[0]->maxv,nc->val)); 51 } 52 else 53 { 54 nc->rm=nc->son[0]->rm; 55 nc->maxv=max(nc->val+nc->son[0]->rm,nc->son[0]->maxv); 56 } 57 return; 58 } 59 nc->lm=max(nc->son[0]->lm,nc->son[0]->sum+max(nc->son[1]->lm,0)+nc->val); 60 nc->rm=max(nc->son[1]->rm,nc->son[1]->sum+max(nc->son[0]->rm,0)+nc->val); 61 nc->maxv=max(max(max(nc->son[0]->maxv,nc->son[1]->maxv),nc->val),max(nc->son[0]->rm+nc->val+nc->son[1]->lm,max(nc->val,max(nc->val+nc->son[1]->lm,nc->son[0]->rm+nc->val)))); 62 } 63 void plaz(node* nc) 64 { 65 node* tmp=nc->son[0]; 66 nc->son[0]=nc->son[1]; 67 nc->son[1]=tmp; 68 int ti=nc->lm; 69 nc->lm=nc->rm; 70 nc->rm=ti; 71 } 72 void pushdown(node *nc) 73 { 74 if(nc->set) 75 { 76 if(nc->son[0]->siz) 77 { 78 nc->son[0]->set=1; 79 nc->son[0]->setv=nc->setv; 80 nc->son[0]->sum=nc->son[0]->siz*nc->son[0]->setv; 81 nc->son[0]->val=nc->setv; 82 } 83 if(nc->son[1]->siz) 84 { 85 nc->son[1]->set=1; 86 nc->son[1]->setv=nc->setv; 87 nc->son[1]->sum=nc->son[1]->siz*nc->son[1]->setv; 88 nc->son[1]->val=nc->setv; 89 } 90 if(nc->setv>0) 91 { 92 if(nc->son[1]->siz) 93 { 94 nc->son[1]->lm=nc->son[1]->sum; 95 nc->son[1]->rm=nc->son[1]->sum; 96 nc->son[1]->maxv=nc->son[1]->sum; 97 } 98 if(nc->son[0]->siz) 99 { 100 nc->son[0]->lm=nc->son[0]->sum; 101 nc->son[0]->rm=nc->son[0]->sum; 102 nc->son[0]->maxv=nc->son[0]->sum; 103 } 104 } 105 else 106 { 107 if(nc->son[1]->siz) 108 { 109 nc->son[1]->lm=nc->setv; 110 nc->son[1]->rm=nc->setv; 111 nc->son[1]->maxv=nc->setv; 112 } 113 if(nc->son[0]->siz) 114 { 115 nc->son[0]->lm=nc->setv; 116 nc->son[0]->rm=nc->setv; 117 nc->son[0]->maxv=nc->setv; 118 } 119 } 120 nc->setv=0; 121 nc->set=0; 122 } 123 if(nc->laz) 124 { 125 nc->son[0]->laz^=1; 126 nc->son[1]->laz^=1; 127 nc->laz=0; 128 plaz(nc->son[0]); 129 plaz(nc->son[1]); 130 } 131 } 132 void rot(node* x,node* &k) 133 { 134 node* y=x->fa; 135 node* z=y->fa; 136 int lx=y->son[1]==x; 137 int rx=lx^1; 138 if(y==k) 139 { 140 k=x; 141 } 142 else 143 { 144 z->son[z->son[1]==y]=x; 145 } 146 x->fa=z; 147 y->fa=x; 148 x->son[rx]->fa=y; 149 y->son[lx]=x->son[rx]; 150 x->son[rx]=y; 151 pushup(y); 152 pushup(x); 153 } 154 void splay(node* x,node* &k) 155 { 156 while(x!=k) 157 { 158 node* y=x->fa; 159 node* z=y->fa; 160 if(y!=k) 161 { 162 if((y->son[0]==x)^(z->son[0]==y)) 163 { 164 rot(x,k); 165 } 166 else 167 { 168 rot(y,k); 169 } 170 } 171 rot(x,k); 172 } 173 } 174 node* find(node* x,int rk) 175 { 176 pushdown(x); 177 if(rk<=x->son[0]->siz) 178 { 179 return find(x->son[0],rk); 180 } 181 else 182 { 183 if(rk==x->son[0]->siz+1) 184 { 185 return x; 186 } 187 else 188 { 189 return find(x->son[1],rk-1-x->son[0]->siz); 190 } 191 } 192 } 193 int fri; 194 void build(int l,int r,node* nc,int x) 195 { 196 if(r<l) 197 { 198 nc->son[x]=fail; 199 return; 200 } 201 if(x==3) 202 { 203 int mid=(l+r)/2; 204 build(l,mid-1,nc,0); 205 build(mid+1,r,nc,1); 206 nc->val=v[mid]; 207 pushup(nc); 208 return; 209 } 210 if(l==r) 211 { 212 node* tmp=new node(); 213 tmp->fa=nc; 214 tmp->siz=1; 215 tmp->val=v[l]; 216 tmp->sum=v[l]; 217 nc->son[x]=tmp; 218 tmp->son[0]=fail; 219 tmp->son[1]=fail; 220 tmp->lm=v[l]; 221 tmp->rm=v[l]; 222 tmp->maxv=v[l]; 223 if(fri&&(l==1||l==n+2)) 224 { 225 tmp->vod=1; 226 } 227 return; 228 } 229 int mid=(l+r)/2; 230 node* tmp=new node(); 231 tmp->fa=nc; 232 tmp->val=v[mid]; 233 nc->son[x]=tmp; 234 tmp->lm=v[mid]; 235 tmp->rm=v[mid]; 236 tmp->maxv=v[mid]; 237 build(l,mid-1,tmp,0); 238 build(mid+1,r,tmp,1); 239 if(fri&&(mid==1||mid==n+2)) 240 { 241 tmp->vod=1; 242 } 243 pushup(tmp); 244 } 245 void del(node* x) 246 { 247 if(x->son[0]->siz) 248 del(x->son[0]); 249 if(x->son[1]->siz) 250 del(x->son[1]); 251 delete x; 252 } 253 int main() 254 { 255 scanf("%d%d",&n,&m); 256 for(int i=2;i<=n+1;i++) 257 { 258 scanf("%d",&v[i]); 259 } 260 root=new node(); 261 fail=new node(); 262 fail->son[0]=fail; 263 fail->son[1]=fail; 264 fail->lm=0; 265 fail->rm=0; 266 fail->maxv=0; 267 fri=1; 268 build(1,n+2,root,3); 269 fri=0; 270 root->fa=root; 271 for(int i=1;i<=m;i++) 272 { 273 scanf("%s",op); 274 if(op[0]=='I') 275 { 276 scanf("%d%d",&p0,&n0); 277 node* x=find(root,p0+1); 278 node* y=find(root,p0+2); 279 splay(x,root); 280 splay(y,root->son[1]); 281 for(int j=1;j<=n0;j++) 282 { 283 scanf("%d",&v[j]); 284 } 285 node* rt=new node(); 286 build(1,n0,rt,3); 287 rt->fa=root->son[1]; 288 root->son[1]->son[0]=rt; 289 pushup(root->son[1]); 290 pushup(root); 291 n+=n0; 292 } 293 if(op[0]=='D') 294 { 295 scanf("%d%d",&p0,&p1); 296 node* x=find(root,p0); 297 node* y=find(root,p0+p1+1); 298 splay(x,root); 299 splay(y,root->son[1]); 300 n-=root->son[1]->son[0]->siz; 301 del(root->son[1]->son[0]); 302 root->son[1]->son[0]=fail; 303 pushup(root->son[1]); 304 pushup(root); 305 } 306 if(op[0]=='M'&&op[2]=='K') 307 { 308 scanf("%d%d%d",&p0,&p1,&c); 309 node* x=find(root,p0); 310 node* y=find(root,p1+p0+1); 311 splay(x,root); 312 splay(y,root->son[1]); 313 root->son[1]->son[0]->set=1; 314 root->son[1]->son[0]->setv=c; 315 root->son[1]->son[0]->sum=root->son[1]->son[0]->setv*root->son[1]->son[0]->siz; 316 root->son[1]->son[0]->val=root->son[1]->son[0]->setv; 317 if(root->son[1]->son[0]->setv>0) 318 { 319 root->son[1]->son[0]->lm=root->son[1]->son[0]->sum; 320 root->son[1]->son[0]->rm=root->son[1]->son[0]->sum; 321 root->son[1]->son[0]->maxv=root->son[1]->son[0]->sum; 322 } 323 else 324 { 325 root->son[1]->son[0]->lm=root->son[1]->son[0]->setv; 326 root->son[1]->son[0]->rm=root->son[1]->son[0]->setv; 327 root->son[1]->son[0]->maxv=root->son[1]->son[0]->setv; 328 } 329 pushup(root->son[1]); 330 pushup(root); 331 } 332 if(op[0]=='R') 333 { 334 scanf("%d%d",&p0,&p1); 335 node* x=find(root,p0); 336 node* y=find(root,p1+p0+1); 337 splay(x,root); 338 splay(y,root->son[1]); 339 root->son[1]->son[0]->laz^=1; 340 node* tmp=root->son[1]->son[0]->son[0]; 341 root->son[1]->son[0]->son[0]=root->son[1]->son[0]->son[1]; 342 root->son[1]->son[0]->son[1]=tmp; 343 int tt=root->son[1]->son[0]->lm; 344 root->son[1]->son[0]->lm=root->son[1]->son[0]->rm; 345 root->son[1]->son[0]->rm=tt; 346 pushup(root->son[1]); 347 pushup(root); 348 } 349 if(op[0]=='G') 350 { 351 scanf("%d%d",&p0,&p1); 352 node* x=find(root,p0); 353 node* y=find(root,p1+p0+1); 354 splay(x,root); 355 splay(y,root->son[1]); 356 printf("%d\n",root->son[1]->son[0]->sum); 357 } 358 if(op[0]=='M'&&op[2]=='X') 359 { 360 printf("%d\n",root->maxv); 361 } 362 } 363 del(root); 364 delete fail; 365 return 0; 366 }