LCT notes (luogu P3690)

LCT maintenance of splay keyword is depth;
pushdown and pushrev are two modes of operation, attention only in makeroot in direct pushrev
front splay put before all of this node marked the node labeled downstream
LCT own several operations to understand :
Access: open a path to the root of x

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
inline int read(){
	char c=getchar();int t=0,f=1;
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
	return t*f;
}
struct node{
	int ch[2],sum,val,fa,rev;
}t[maxn];
#define lc t[x].ch[0]
#define rc t[x].ch[1]
inline bool isrt(int x){
	return (t[t[x].fa].ch[0]!=x)&&(t[t[x].fa].ch[1]!=x);
}
inline void pushup(int x){
	t[x].sum=t[lc].sum^t[rc].sum^t[x].val;
}
inline void pushrev(int x){
	swap(lc,rc);t[x].rev^=1;
}
inline void pushdown(int x){
	if(t[x].rev){
		if(lc)pushrev(lc);
		if(rc)pushrev(rc);
		t[x].rev=0;
	}
}
inline void rotate(int x){
	int y=t[x].fa,z=t[y].fa,k=t[y].ch[1]==x;
	if(!isrt(y))t[z].ch[t[z].ch[1]==y]=x;
	t[x].fa=z;t[y].fa=x;t[t[x].ch[k^1]].fa=y;
	t[y].ch[k]=t[x].ch[k^1];t[x].ch[k^1]=y;
	pushup(y);pushup(x);
}
int st[maxn],top;
inline void splay(int x){
	top=0;
	st[++top]=x;
	int v=x;
	while(!isrt(v)){
		st[++top]=t[v].fa;v=t[v].fa;
	}
	while(top){
		pushdown(st[top--]);
	}
	for(;!isrt(x);rotate(x)){
		int y=t[x].fa,z=t[y].fa;
		if(isrt(y))continue;
		(t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);
	}
	pushup(x);
}
inline void access(int x){
	for(int v=0;x;x=t[v=x].fa){
		splay(x);rc=v;//这里是维护splay中按深度排序的性质
		pushup(x);
	}
}
inline void makeroot(int x){
	access(x);splay(x);pushrev(x);//这里是因为我们lct中的splay的维护是以深度为关键字的。将x提到根,反转了x到根这一段的深度顺序
}
inline int findroot(int x){
	access(x);splay(x);
	while(lc){pushdown(x);x=lc;}
	splay(x);
	return x;
}
inline void split(int x,int y){//提出x到y的路径
	makeroot(x);access(y);
	splay(y);
}
inline void link(int x,int y){//这里的link和cut考虑的都是合法情况
	makeroot(x);t[x].fa=y;
}
inline void cut(int x,int y){
	makeroot(x);
	if(findroot(y)==x&&t[y].fa==x&&(!t[y].ch[0])){
		t[y].fa=0;t[x].ch[1]=0;pushup(x);
	}
}
int n,m;
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)t[i].val=read();
	int opt,x,y;
	while(m--){
		opt=read();x=read(),y=read();
		if(opt==0){
			split(x,y);
			printf("%d\n",t[y].sum);
		}
		if(opt==1){
			link(x,y);
		}
		if(opt==2){
			cut(x,y);
		}
		if(opt==3){
			splay(x);t[x].val=y;
		}
	}
	return 0;
}

Published 62 original articles · won praise 1 · views 1017

Guess you like

Origin blog.csdn.net/wmhtxdy/article/details/103676867