【模板】动态树 Link-Cut Tree

posted on 2022-08-17 18:05:59 | under 模板 | source

template<int N> struct lctree{
	int val[N+10],sum[N+10],fa[N+10],ch[N+10][2],rev[N+10];
	bool getson(int p){return ch[fa[p]][1]==p;}
	bool isroot(int p){return !p||ch[fa[p]][getson(p)]!=p;}
	void maintain(int p){sum[p]=val[p]^sum[ch[p][0]]^sum[ch[p][1]];}
	void pushdown(int p){if(rev[p]) swap(ch[p][0],ch[p][1]),rev[ch[p][0]]^=1,rev[ch[p][1]]^=1,rev[p]^=1;}
	void update(int p){if(!isroot(p)) update(fa[p]); pushdown(p);}
	void connect(int p,int q,int r){fa[p]=q,ch[q][r]=p;}//p->q
	void rotate(int p){int f=fa[p],r=getson(p);if(fa[p]=fa[f],!isroot(f)) connect(p,fa[f],getson(f));connect(ch[p][r^1],f,r),connect(f,p,r^1),maintain(f),maintain(p);}
	void splay(int p){for(update(p);!isroot(p);rotate(p)) if(!isroot(fa[p])) rotate(getson(p)==getson(fa[p])?fa[p]:p);}
	int access(int p){int y=0;for(;p;p=fa[y=p]) splay(p),ch[p][1]=y,maintain(p);return y;}
	void makeroot(int p){access(p),splay(p),rev[p]^=1;}
	int findroot(int p){access(p),splay(p);while(ch[p][0]) p=ch[p][0];return p;}
	void split(int x,int y){makeroot(x),access(y),splay(y);}
	void link(int x,int y){makeroot(x),fa[x]=y;}
	void cut(int x,int y){split(x,y);if(fa[x]==y&&!ch[x][1]) fa[x]=ch[y][0]=0; maintain(y);}
	void modify(int x,int y){splay(x),val[x]=y,maintain(x);}
	int lca(int x,int y){return access(x),access(y);}
};
posted @ 2022-11-06 19:11  caijianhong  阅读(10)  评论(0编辑  收藏  举报