ZTL — 数据结构 — LinkCutTree

class LinkCutTree{
	public:
	class LCT_Splay{
		public:
		int val[maxn];
		int fa[maxn], son[maxn][2], st[maxn], tot, totp;
		bool rev[maxn];		
		inline void pushup(int x) {val[x] = val[son[x][0]] ^ val[son[x][1]] ^ a[x];}
		inline void rever(int x) {
			int tmp = son[x][0];
			son[x][0] = son[x][1];
			son[x][1] = tmp;
			rev[x] ^= 1; 
		}
		inline void pushdown(int x){
			if(rev[x]){
				rever(son[x][0]); rever(son[x][1]);
				rev[x] = 0;
			}
		}
		inline bool notroot(int x) {return (son[fa[x]][0] == x) || (son[fa[x]][1] == x);}
		inline void rotate(int x){
			int y = fa[x], z = fa[y]; bool zson = (son[z][0] ^ y), yson = (son[y][0] ^ x);
			int bo = (son[x][!yson]);
			if(notroot(y)) son[z][zson] = x;
			son[x][!yson] = y; son[y][yson] = bo;
			if(bo) fa[bo] = y;
			fa[y] = x; fa[x] = z;
			pushup(y);
		}
		inline void splay(int x){
			int y = x, top = 0; st[++top] = y;
//			cout << "ho" << endl;
    		while(notroot(y)) st[++top] = y = fa[y];
//    		cout << "ho bo" << endl; 
    		while(top) pushdown(st[top--]);
//    		cout << "stttt" << endl;
    		while(notroot(x)){
    			y = fa[x], top = fa[y];
    			if(notroot(y)) rotate(((son[y][0]^x) ^ (son[top][0]^y)) ? x : y);
    			rotate(x);
    		}
    		pushup(x);
		}
	}LCT_Splay;
	private:
	inline void access(int x){
		for(int y = 0; x; x = LCT_Splay.fa[y=x]){
			LCT_Splay.splay(x);
			LCT_Splay.son[x][1] = y;
			LCT_Splay.pushup(x);
		}
	}
	inline void changeroot(int x){
		access(x); LCT_Splay.splay(x); 
		LCT_Splay.rever(x);
	}
	inline int findroot(int x){
		access(x); LCT_Splay.splay(x);
		while(LCT_Splay.son[x][0]) LCT_Splay.pushdown(x), x = LCT_Splay.son[x][0];
		LCT_Splay.splay(x);
		return x;
	}
	public:
	inline void split(int x, int y){
		changeroot(x);
		
		access(y); LCT_Splay.splay(y);
	}
	inline void connect(int x, int y){
		changeroot(x);
		if(findroot(y) ^ x) LCT_Splay.fa[x] = y;
	}
	inline void disconnect(int x, int y){
		changeroot(x);
		if(findroot(y) == x && LCT_Splay.fa[y] == x && !LCT_Splay.son[y][0]){
			LCT_Splay.fa[y] = LCT_Splay.son[x][1] = 0;
			LCT_Splay.pushup(x);
		}
	} 
	inline int getval(int x){return LCT_Splay.val[x];}
	inline void toroot(int x){LCT_Splay.splay(x);}
}LCT;
posted @ 2020-10-16 16:57  zimindaada  阅读(79)  评论(0编辑  收藏  举报