让我们响应王学长的号召勇敢的分开写splay和lct吧!
分开写大法好!!!!!!!!!!!杜教的ch[4]弱爆了!!!!
1 #include <stdio.h> 2 #include <algorithm> 3 char ch; 4 inline void read(int &x) 5 { 6 x=0;ch=getchar(); 7 while(ch<=32) ch=getchar(); 8 while(ch>32) x=x*10+ch-48,ch=getchar(); 9 }; 10 11 inline void G(int x){while(x--) getchar();} 12 13 #define MAXN 50005 14 #define MAXM 250005 15 16 int n,q; 17 18 struct Info{ 19 int mi,size; 20 long long sum; 21 }; 22 23 const int NULL_TAG=0; 24 const Info NULL_INFO=(Info){2147483647,0,0}; 25 26 inline Info operator + (const Info &a,const Info &b) 27 { 28 return (Info){std::min(a.mi,b.mi),a.size+b.size,a.sum+b.sum}; 29 }; 30 31 inline Info operator * (const Info &a,const int &b) 32 { 33 return a.size ? (Info){a.mi+b,a.size,a.sum+1LL*a.size*b}: a; 34 }; 35 36 struct TopTree{ 37 38 struct splay_node{ 39 splay_node *ch[2],*fa; 40 Info x,sum; 41 int tag,tag_sum; 42 43 inline void add_tag(int t) 44 { 45 tag=tag+t;tag_sum=tag_sum+t; 46 x=x*t;sum=sum*t; 47 }; 48 49 inline void down() 50 { 51 if(ch[0]) ch[0]->add_tag(tag); 52 if(ch[1]) ch[1]->add_tag(tag); 53 tag=NULL_TAG; 54 }; 55 56 inline void update() 57 { 58 sum=x; 59 if(ch[0]) sum=sum+ch[0]->sum; 60 if(ch[1]) sum=sum+ch[1]->sum; 61 }; 62 63 }; 64 65 splay_node _nodes[MAXN]; 66 67 inline int get_parent(splay_node *x,splay_node *&fa) 68 { 69 return (fa=x->fa) ? fa->ch[1]==x : -1; 70 }; 71 72 inline void rotate(splay_node *x) 73 { 74 int t1,t2; 75 splay_node *fa,*gfa; 76 t1=get_parent(x,fa); 77 t2=get_parent(fa,gfa); 78 if((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa; 79 fa->fa=x;x->fa=gfa;x->ch[t1^1]=fa; 80 if(t2!=-1) gfa->ch[t2]=x; 81 fa->update(); 82 }; 83 84 inline void pushdown(splay_node *x) 85 { 86 static splay_node *stack[MAXN]; 87 int cnt=0; 88 while(x) stack[cnt++]=x,x=x->fa; 89 while(cnt--) stack[cnt]-> down(); 90 }; 91 92 inline splay_node * splay(splay_node *x) 93 { 94 pushdown(x); 95 while(1){ 96 int t1,t2; 97 splay_node *fa,*gfa; 98 t1=get_parent(x,fa); 99 if(t1==-1) break; 100 t2=get_parent(fa,gfa); 101 if(t2==-1){ 102 rotate(x);break; 103 }else if(t1==t2){ 104 rotate(fa);rotate(x); 105 }else{ 106 rotate(x);rotate(x); 107 }; 108 }; 109 x->update(); 110 return x; 111 }; 112 113 inline splay_node * join(splay_node *L,splay_node *R) 114 { 115 if(!L) return R; 116 if(!R) return L; 117 while(L->ch[1]) L-> down(),L=L->ch[1]; 118 splay(L)->ch[1]=R; 119 R->fa=L; 120 L->update(); 121 return L; 122 }; 123 124 static splay_node *root[MAXN]; 125 126 struct lct_node{ 127 lct_node *ch[2],*fa,*first,*last; 128 bool rev; 129 130 Info x,sum,tree,all; 131 int chain_tag,tree_tag; 132 133 inline void add_rev_tag() 134 { 135 std::swap(ch[0],ch[1]); 136 std::swap(first,last); 137 rev^=1; 138 }; 139 140 inline void add_chain_tag(int t) 141 { 142 x=x*t;sum=sum*t; 143 chain_tag=chain_tag+t; 144 all=sum+tree; 145 }; 146 147 inline void add_tree_tag(int t); 148 149 inline void down() 150 { 151 if(rev){ 152 if(ch[0]) ch[0]->add_rev_tag(); 153 if(ch[1]) ch[1]->add_rev_tag(); 154 rev=0; 155 }; 156 if(ch[0]) ch[0]->add_chain_tag(chain_tag),ch[0]->add_tree_tag(tree_tag); 157 if(ch[1]) ch[1]->add_chain_tag(chain_tag),ch[1]->add_tree_tag(tree_tag); 158 chain_tag=tree_tag=NULL_TAG; 159 }; 160 161 inline void update(); 162 }; 163 164 static lct_node lct[MAXN]; 165 166 inline int get_parent(lct_node *x,lct_node *&fa) 167 { 168 return (fa=x->fa) ? fa->ch[0]==x?0:fa->ch[1]==x?1:-1 : -1; 169 }; 170 171 inline void rotate(lct_node *x) 172 { 173 int t1,t2; 174 lct_node *fa,*gfa; 175 t1=get_parent(x,fa); 176 t2=get_parent(fa,gfa); 177 if((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa; 178 fa->fa=x;x->fa=gfa;x->ch[t1^1]=fa; 179 if(t2!=-1) gfa->ch[t2]=x; 180 fa->update(); 181 }; 182 183 inline void pushdown(lct_node *x) 184 { 185 static lct_node *stack[MAXN]; 186 int cnt=0; 187 while(1){ 188 stack[cnt++]=x; 189 lct_node *fa=x->fa; 190 if(!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break; 191 x=fa; 192 }; 193 while(cnt--) stack[cnt]-> down(); 194 }; 195 196 inline lct_node * splay(lct_node *x) 197 { 198 pushdown(x); 199 while(1){ 200 int t1,t2; 201 lct_node *fa,*gfa; 202 t1=get_parent(x,fa); 203 if(t1==-1) break; 204 t2=get_parent(fa,gfa); 205 if(t2==-1){ 206 rotate(x);break; 207 }else if(t1==t2){ 208 rotate(fa);rotate(x); 209 }else{ 210 rotate(x);rotate(x); 211 }; 212 }; 213 x->update(); 214 return x; 215 }; 216 217 inline lct_node * access(lct_node *x); 218 inline void setroot(int x); 219 inline void modifychain(int x,int y,int t); 220 inline void modifysubtree(int x,int y,int t); 221 inline Info query_chain(int x,int y); 222 inline Info query_subtree(int x,int y); 223 inline void link(int x,int y); 224 inline void cut(int x,int y); 225 inline void init(int *a); 226 227 }_toptree; 228 229 TopTree::lct_node TopTree::lct[MAXN]; 230 TopTree::splay_node *TopTree::root[MAXN]; 231 232 inline void TopTree::lct_node::add_tree_tag(int t) 233 { 234 tree=tree*t; 235 tree_tag=tree_tag+t; 236 all=sum+tree; 237 int id=this-TopTree::lct; 238 if(root[id]){ 239 root[id]->add_tag(t); 240 }; 241 }; 242 243 inline void TopTree::lct_node::update() 244 { 245 sum=x;tree=NULL_INFO; 246 int id=this-TopTree::lct; 247 if(root[id]){ 248 tree=tree+root[id]->sum; 249 }; 250 if(ch[0]) sum=sum+ch[0]->sum,tree=tree+ch[0]->tree; 251 if(ch[1]) sum=sum+ch[1]->sum,tree=tree+ch[1]->tree; 252 all=sum+tree; 253 first=ch[0]?ch[0]->first:this; 254 last=ch[1]?ch[1]->last:this; 255 }; 256 257 inline TopTree::lct_node * TopTree::access(TopTree::lct_node *x) 258 { 259 TopTree::lct_node *ret=NULL; 260 while(x){ 261 splay(x); 262 int X=x-TopTree::lct; 263 if(x->ch[1]){ 264 int id=x->ch[1]->first-TopTree::lct; 265 splay_node *p=_nodes+id; 266 p->ch[0]=root[X]; 267 if(root[X]) root[X]->fa=p; 268 p->ch[1]=NULL; 269 p->fa=NULL; 270 p->x=x->ch[1]->all; 271 p->tag=p->tag_sum=NULL_TAG; 272 p->update(); 273 root[X]=p; 274 x->ch[1]=NULL; 275 }; 276 if(ret){ 277 int id=ret->first-TopTree::lct; 278 splay_node *p=_nodes+id; 279 splay(p); 280 if(p->ch[0]) p->ch[0]->fa=NULL; 281 if(p->ch[1]) p->ch[1]->fa=NULL; 282 root[X]=join(p->ch[0],p->ch[1]); 283 ret->add_chain_tag(p->tag_sum),ret->add_tree_tag(p->tag_sum); 284 x->ch[1]=ret; 285 }; 286 x->update(); 287 ret=x;x=x->fa; 288 }; 289 return ret; 290 }; 291 292 inline void TopTree::setroot(int x) 293 { 294 access(TopTree::lct+x)->add_rev_tag(); 295 }; 296 297 inline void TopTree::modifychain(int x,int y,int t) 298 { 299 setroot(x); 300 access(TopTree::lct+y)->add_chain_tag(t); 301 }; 302 303 inline void TopTree::modifysubtree(int x,int y,int t) 304 { 305 setroot(x); 306 access(TopTree::lct+y),splay(TopTree::lct+y); 307 TopTree::lct[y].x=TopTree::lct[y].x*t; 308 if(root[y]) root[y]->add_tag(t); 309 TopTree::lct[y].update(); 310 }; 311 312 inline Info TopTree::query_chain(int x,int y) 313 { 314 setroot(x); 315 return access(TopTree::lct+y)->sum; 316 }; 317 318 inline Info TopTree::query_subtree(int x,int y) 319 { 320 setroot(x); 321 access(TopTree::lct+y),splay(TopTree::lct+y); 322 return root[y] ? TopTree::lct[y].x+root[y]->sum : TopTree::lct[y].x; 323 }; 324 325 inline void TopTree::link(int x,int y) 326 { 327 setroot(x); 328 splay(TopTree::lct+x)->fa=TopTree::lct+y; 329 access(TopTree::lct+y); 330 splay(TopTree::lct+y)->ch[1]=TopTree::lct+x; 331 TopTree::lct[y].update(); 332 }; 333 334 inline void TopTree::cut(int x,int y) 335 { 336 setroot(x); 337 access(TopTree::lct+y); 338 TopTree::lct_node *t=splay(TopTree::lct+y); 339 t->ch[0]->fa=NULL;t->ch[0]=NULL; 340 t->update(); 341 }; 342 343 inline void TopTree::init(int *a) 344 { 345 int i; 346 for(i=1;i<=n;i++){ 347 TopTree::lct[i].first=TopTree::lct[i].last=TopTree::lct+i; 348 TopTree::lct[i].x=TopTree::lct[i].sum=TopTree::lct[i].all=(Info){a[i],1,a[i]}; 349 TopTree::lct[i].tree=NULL_INFO; 350 TopTree::lct[i].chain_tag=TopTree::lct[i].tree_tag=NULL_TAG; 351 }; 352 };