【模板】Link-Cut-Tree

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82960094

参考题目:洛谷P3690


解析:

联赛完后统一更模板题解析。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline
int getint(){
	re int num;
	re char c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
	return num;
}

inline void outint(int a){
	static char ch[13];
	if(a==0)pc('0');
	while(a)ch[++ch[0]]=a-a/10*10,a/=10;
	while(ch[0])pc(ch[ch[0]--]^48);
}

typedef struct splay_node *point;
struct splay_node{
	point son[2],fa;
	bool tag;
	int val,xr;
	
	point &lc(){return son[0];}
	point &rc(){return son[1];}
	
	void pushdown(){
		if(tag){
			swap(lc(),rc());
			if(lc())lc()->tag^=1;
			if(rc())rc()->tag^=1;
			tag=0;
		}
	}
	
	void init(int _val=0){
		son[0]=son[1]=fa=NULL;
		tag=0;xr=val=_val;
	}
	
	void pushup(){
		xr=(lc()?lc()->xr:0)^(rc()?rc()->xr:0)^val;
	}
	
	bool isroot(){return !fa||(fa->lc()!=this&&fa->rc()!=this);}
	bool which(){return fa->rc()==this;}
};

cs int N=300005;
struct Link_Cut_Tree{
	point tr[N];
	
	void init(int n){
		for(int re i=1;i<=n;++i){
			tr[i]=(point)malloc(sizeof(splay_node));
			tr[i]->init(getint());
		}
	}
	
	void Rotate(point now){
		point Fa=now->fa,FA=Fa->fa;
		bool pos=now->which();
		if(FA&&!Fa->isroot())FA->son[Fa->which()]=now;
		Fa->son[pos]=now->son[!pos];
		if(Fa->son[pos])Fa->son[pos]->fa=Fa;
		now->son[!pos]=Fa;
		Fa->fa=now;
		now->fa=FA;
		Fa->pushup();
		now->pushup(); 
	}
	
	void Splay(point now){
		static point q[N];
		static int qn;
		q[qn=1]=now;
		for(point Fa=now;!Fa->isroot();Fa=Fa->fa)q[++qn]=Fa->fa;
		for(int re i=qn;i;--i)q[i]->pushdown();
		for(point Fa=now->fa;!now->isroot();Rotate(now),Fa=now->fa)
		if(!Fa->isroot())Rotate(now->which()==Fa->which()?Fa:now);
	}
	
	void access(point now){
		for(point son=NULL;now;son=now,now=now->fa){
			Splay(now);now->rc()=son;
			now->pushup();
		}
	}
	
	void makeroot(point now){
		access(now);
		Splay(now);
		now->tag^=1;
	}
	
	point findroot(point now){
		access(now);
		Splay(now);
		while(now->lc())now=now->lc();
		return now;
	}
	
	void link(point u,point v){
		makeroot(u);
		if(findroot(v)!=u)u->fa=v;
	}
	void Link(int u,int v){link(tr[u],tr[v]);}
	
	void cut(point u,point v){
		if(findroot(u)!=findroot(v))return ;//去掉也能过,那是因为洛谷数据水。。。
		makeroot(u);
		access(v);
		Splay(v);
		if(u->rc()!=NULL||u->fa!=v||v->son[!u->which()]!=NULL)return ;
		v->lc()=u->fa=NULL;
	}
	void Cut(int u,int v){cut(tr[u],tr[v]);}
	
	int query(point u,point v){
		makeroot(u);
		access(v);
		Splay(v);
		return v->xr;
	}
	int Query(int u,int v){return query(tr[u],tr[v]);}
	
	void update(point u,int v){
		u->val=v;
		access(u);
		Splay(u);
	}
	void Update(int u,int v){update(tr[u],v);}
	
}LCT;

int n,m;
signed main(){
	n=getint();
	m=getint();
	LCT.init(n);
	while(m--){
		int op=getint(),u=getint(),v=getint();
		switch(op){
			case 0:outint(LCT.Query(u,v)),pc('\n');break;
			case 1:LCT.Link(u,v);break;
			case 2:LCT.Cut(u,v);break;
			case 3:LCT.Update(u,v);break;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/82960094
今日推荐