【BZOJ 3282】Tree 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;
}
这样就行啦
NOI 2017 Bless All

浙公网安备 33010602011771号