结构体版,常数较小:
namespace LCT{
#define N 500100
#define RI register
#define F(x) t[(x)].fa
#define lc(x) t[(x)].ch[0]
#define rc(x) t[(x)].ch[1]
#define notrt(x) (lc(F((x)))==x||rc(F((x)))==x)
#define pushup(x) (t[(x)].ss=t[lc((x))].ss^t[rc((x))].ss^t[(x)].val)
struct node{
int fa,ch[2],rv,val,ss;
inline void nwnode(int x){val=ss=x;}
}t[N];
inline void pushdown(int x)
{
if(!t[x].rv) return;
swap(lc(x),rc(x));
if(lc(x)) t[lc(x)].rv^=1;
if(rc(x)) t[rc(x)].rv^=1;
t[x].rv=0;
}
inline void rotate(int x)
{
RI int y=F(x),z=F(y),dr=(rc(y)==x);
F(t[x].ch[dr^1])=y;t[y].ch[dr]=t[x].ch[dr^1];
F(x)=z;if(notrt(y)) t[z].ch[(rc(z)==y)]=x;
F(y)=x;t[x].ch[dr^1]=y;pushup(y);
}
void dn(int x){if(notrt(x)) dn(F(x));pushdown(x);}
void splay(int x)
{
RI int y,z;dn(x);
for(;notrt(x);){
y=F(x);z=F(y);
if(notrt(y))
((rc(z)==y)^(rc(y)==x))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
inline void setrs(int x,int rs){splay(x);rc(x)=rs;pushup(x);}
inline void access(int x){for(setrs(x,0);F(x);x=F(x)) setrs(F(x),x);}
inline void mkrt(int x){access(x);splay(x);t[x].rv^=1;}
inline int fdrt(int x){access(x);splay(x);for(;lc(x);x=lc(x));return x;}
inline bool iscon(int x,int y){mkrt(x);return x==fdrt(y);}
inline void lk(int x,int y){mkrt(x);F(x)=y;}
inline void cut(int x,int y){setrs(x,0);setrs(y,0);F(x)==y?F(x)=0:F(y)=0;}
#undef N
}
指针版,似乎常数有点大(跑的比结构体还慢?):
namespace LCT{
#define N 500100
struct node{
node *fa,*ch[2];
int rv,val,ss;
node(){fa=ch[0]=ch[1]=NULL;}
inline bool notrt() {return (fa!=NULL && (fa->ch[0]==this || fa->ch[1]==this));}
inline void pushup(){
ss=val;
if(ch[0]!=NULL) ss^=ch[0]->ss;
if(ch[1]!=NULL) ss^=ch[1]->ss;
}
inline void pushdown(){
if(!rv) return;
swap(ch[0],ch[1]);
if(ch[0]!=NULL) ch[0]->rv^=1;
if(ch[1]!=NULL) ch[1]->rv^=1;
rv=0;
}
}t[N];
inline void rotate(node *x)
{
node *y=x->fa,*z=y->fa;int dr=(y->ch[1]==x);node *q=x->ch[dr^1];
if(q!=NULL) q->fa=y;y->ch[dr]=q;
x->fa=z;if(y->notrt()) z->ch[(z->ch[1]==y)]=x;
y->fa=x;x->ch[dr^1]=y;y->pushup();
}
void dn(node *x){if(x->notrt()) dn(x->fa);x->pushdown();}
void splay(node *x)
{
node *y,*z;dn(x);
for(;x->notrt();){
y=x->fa;z=y->fa;
if(y->notrt())
((z->ch[1]==y)^(y->ch[1]==x))?rotate(x):rotate(y);
rotate(x);
}
x->pushup();
}
inline void setrs(node *x,node *rs){splay(x);x->ch[1]=rs;x->pushup();}
inline void access(node *x){for(setrs(x,NULL);x->fa!=NULL;x=x->fa) setrs(x->fa,x);}
inline void mkrt(node *x){access(x);splay(x);x->rv^=1;}
inline node* fdrt(node *x){access(x);splay(x);for(;x->ch[0];x=x->ch[0]);return x;}
inline bool iscon(node *x,node *y){mkrt(x);return x==fdrt(y);}
inline void lk(node *x,node *y){mkrt(x);x->fa=y;}
inline void cut(node *x,node *y){
setrs(x,NULL);setrs(y,NULL);
if(x->fa==y) x->fa=NULL;else if(y->fa==x) y->fa=NULL;
}
#undef N
}