LCT模板

1#


struct nd{
    nd *ch[2],*fa;
    int s,v;
    bool r,isr();
    nd();
    iv rev(),pd(),pu(),cta(nd*x),rot(int d);
}*nul=new nd(),t[N];

bool nd::isr(){
	return fa->ch[0]!=this&&fa->ch[1]!=this;
}

nd::nd(){
    s=r=v=0;
    ch[0]=ch[1]=fa=nul;
}   

iv nd::rev(){
    swap(ch[0],ch[1]);
    r^=1;
}

iv nd::pd(){
    if(!isr()) fa->pd();
    if(r){
        ch[0]->rev();
        ch[1]->rev();
        r=0;
    }
}
iv nd:: pu(){
	s=ch[0]->s+ch[1]->s+v;
}

iv init(){nul->ch[0]=nul->ch[1]=nul->fa=nul;nul->s=0;}
//不知道为什么nd()无法把nul的ch[]和fa初始化为nul 


iv nd::rot(int d){
	nd*k=ch[d^1];
	ch[d^1]=k->ch[d],k->ch[d]->fa=this;
	k->ch[d]=this;
 	if(!isr()) fa->ch[fa->ch[1]==this]=k;
	k->fa=fa,fa=k,pu();
}

iv splay(nd*x){
    x->pd();
    while(!x->isr()){
        nd*y=x->fa,*z=y->fa;
        if(x==y->ch[0]){
            if(y==z->ch[0]) z->rot(1);
            y->rot(1);
        }else{
            if(y==z->ch[1]) z->rot(0);
            y->rot(0);
        }
    }
    x->pu();
}

iv acc(nd*x){
    nd*y=nul;
    while(x!=nul){
        splay(x);
        x->ch[1]=y;
        x->pu();
        y=x;
        x=x->fa;
    }
}

inline nd* find(nd*x){
    acc(x);  
    splay(x);
    while(x->ch[0]!=nul) x=x->ch[0];
    acc(x);
    return x;
}

iv tor(nd*x){
    acc(x);
    splay(x);
    x->rev();
}

iv nd::cta(nd*x){
    tor(x);
    acc(this);
    splay(this);
}

iv cut(nd*x,nd*y){
    x->cta(y);
    if(y->fa==x&&y->ch[1]==nul){   //判断x和y之间是否有边 
        x->ch[0]=y->fa=nul;
        x->pu();
    }
}

iv link(nd*x,nd*y){
    tor(x);
    x->fa=y;
}



2#

struct node{
	node *ch[2],*fa;
	int sz;
	bool rev;
	node();
	inline void reverse();
	inline void pushdown();
	inline void pushup();
	inline void contact(node*x);	//很多修改和查询操作会重复使用 
}*null=new node(),tr[N];

node::node(){
	sz=1;
	rev=0;
	ch[0]=ch[1]=fa=null;
}	

inline void node::reverse(){
	swap(ch[0],ch[1]);
	rev^=1;
}

inline void node::pushdown(){
	if(fa->ch[0]==this||fa->ch[1]==this) fa->pushdown();
	if(rev){
		ch[0]->reverse();
		ch[1]->reverse();
		rev=0;
	}
}
	
inline void node::pushup(){
	sz=ch[0]->sz+ch[1]->sz+1;
}

inline void init(){null->ch[0]=null->ch[1]=null->fa=null;null->sz=0;}
//不知道为什么node()无法把null的ch[]和fa初始化为null 

inline void rotate(node*o,int d){
	node*k=o->ch[d^1];
	o->ch[d^1]=k->ch[d];
	k->ch[d]->fa=o;
	k->ch[d]=o;
	if(o->fa->ch[0]==o) o->fa->ch[0]=k;
	else if(o->fa->ch[1]==o) o->fa->ch[1]=k;
	k->fa=o->fa;
	o->fa=k;
	o->pushup();
}

inline void splay(node*x){
	x->pushdown();
	while(x->fa->ch[0]==x||x->fa->ch[1]==x){
		node*y=x->fa,*z=y->fa;
		if(x==y->ch[0]){
			if(y==z->ch[0]) rotate(z,1);
			rotate(y,1);
		}else{
			if(y==z->ch[1]) rotate(z,0);
			rotate(y,0);
		}
	}
	x->pushup();
}

inline void access(node*x){
	node*y=null;
	while(x!=null){
		splay(x);
		x->ch[1]=y;
		x->pushup();
		y=x;
		x=x->fa;
	}
}

inline node* find(node*x){
	access(x);	
	splay(x);
	while(x->ch[0]!=null) x=x->ch[0];
	access(x);
	return x;
}

/*
inline node* find(node*x){		//这样写被卡过一次 
	while(x->fa!=null) x=x->fa;
	return x;
}
*/ 

inline void toroot(node*x){
	access(x);
	splay(x);
	x->reverse();
}

inline void node::contact(node*x){
	toroot(x);
	access(this);
	splay(this);
}

inline void cut(node*x,node*y){
	x->contact(y);
	if(y->fa==x&&y->ch[1]==null){	//判断x和y之间是否有边 
		x->ch[0]=y->fa=null;
		x->pushup();
	}
}

inline void link(node*x,node*y){
	toroot(x);
	x->fa=y;
}
原文地址:https://www.cnblogs.com/lsq647vsejgfb/p/9496648.html