BZOJ 3282Tree Link Cut Tree模板题
Posted abclzr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3282Tree Link Cut Tree模板题相关的知识,希望对你有一定的参考价值。
知道了为什么要换根(changeroot),access后为什么有时要splay,以及LCT的其他操作,算是比较全面的啦吧,,,
现在才知道这些,,,真心弱,,,
#include<cstdio> #include<algorithm> #define read(x) x=getint() using namespace std; const int N=300003; inline int getint(){char c;int ret=0;for(c=getchar();c<‘0‘||c>‘9‘;c=getchar());for(;c>=‘0‘&&c<=‘9‘;c=getchar())ret=ret*10+c-‘0‘;return ret;} struct node *null; struct node{ node(); node *fa,*ch[2]; int d,rev,w; void push() {if(rev) {ch[0]->rev^=1; ch[1]->rev^=1; rev=0; swap(ch[0],ch[1]);}} void count() {w=ch[0]->w^ch[1]->w^d;} void setc(node *r,bool c) {ch[c]=r; r->fa=this;} bool check() {return fa==null||((fa->ch[0]!=this)&&(fa->ch[1]!=this));} bool pl() {return fa->ch[1]==this;} }*T[N]; node::node() {d=rev=w=0; fa=ch[0]=ch[1]=null;} int n; inline void Build() {null=new node; *null=node();} inline void rotate(node *r){ node *f=r->fa; bool c=r->pl(); if (!f->check()) f->fa->setc(r,f->pl()); else r->fa=f->fa; f->setc(r->ch[!c],c); r->setc(f,!c); f->count(); } inline void update(node *r) {if (!r->check()) update(r->fa); r->push();} inline void splay(node *r){ update(r); for(;!r->check();rotate(r)) if (!r->fa->check()) rotate(r->fa->pl()==r->pl()?r->fa:r); r->count(); } inline node *access(node *r){ node *y=null; for(;r!=null;y=r,r=r->fa){ splay(r); r->setc(y,1); r->count(); } return y; } inline void changeroot(node *r) {access(r)->rev^=1; splay(r);} inline void cut(node *r,node *y) {changeroot(r); access(y); splay(y); y->ch[0]->fa=null; y->ch[0]=null;} inline void link(node *r,node *y) {changeroot(r); r->fa=y;} inline node *findroot(node *r) {access(r); splay(r); while(r->ch[0]!=null) r=r->ch[0]; return r;} int main(){ Build(); read(n); int x,q,a,b; read(q); for(int i=1;i<=n;i++) {T[i]=new node; read(T[i]->d); T[i]->w=T[i]->d;} while (q--){ read(x); read(a); read(b); switch (x){ case 0: changeroot(T[a]); access(T[b]); splay(T[b]); printf("%d\n",T[b]->w); break; case 1: if (findroot(T[a])!=findroot(T[b])) link(T[a],T[b]); break; case 2: if (findroot(T[a])==findroot(T[b])) cut(T[a],T[b]); break; case 3: changeroot(T[a]); T[a]->d=b; T[a]->count(); break; } } return 0; }
这样就行啦
以上是关于BZOJ 3282Tree Link Cut Tree模板题的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 2631 tree 动态树(Link-Cut-Tree)
bzoj2049[Sdoi2008]Cave 洞穴勘测 link-cut-tree