LCT模板

namespace LCT
{
	/*
	这个模板是单点修改点权,然后询问x到y的异或和 
	*/ 
	int fa[maxn];
	int son[maxn][2];
	int s[maxn];
	int v[maxn];
	int st[maxn];
	bool fl[maxn];
	inline bool isroot(int num)//如果返回True,就不是根结点 
	{
		return son[fa[num]][0]==num||son[fa[num]][1]==num;
	}
	inline void pushup(int num)//向上更新,更新val 
	{
		s[num]=s[son[num][0]]^s[son[num][1]]^v[num];
	}
	inline void rever(int num)//交换当前结点的子儿子 
	{
		swap(son[num][0],son[num][1]);
		fl[num]^=1;
	}
	inline void pushdown(int num)//向下更新lazy标记 
	{
		if(fl[num])
		{
	        if(son[num][0])rever(son[num][0]);
	        if(son[num][1])rever(son[num][1]);
	        fl[num]=0;
	    }
	}
	inline void rotate(int x)//splay向上换结点 
	{
	    int y=fa[x],z=fa[y],k=son[y][1]==x,w=son[x][!k];
	    if(isroot(y))son[z][son[z][1]==y]=x;son[x][!k]=y;son[y][k]=w;
	    if(w)fa[w]=y;fa[y]=x;fa[x]=z;
	    pushup(y);
	}
	inline void splay(int x){//只传了一个参数,因为所有操作的目标都是该Splay的根(与普通Splay的区别3)
	    int y=x,z=0;
	    st[++z]=y;//st为栈,暂存当前点到根的整条路径,pushdown时一定要从上往下放标记(与普通Splay的区别4)
	    while(isroot(y))st[++z]=y=fa[y];
	    while(z)pushdown(st[z--]);
	    while(isroot(x)){
	        y=fa[x];z=fa[y];
	        if(isroot(y))
	            rotate((son[y][0]==x)^(son[z][0]==y)?x:y);
	        rotate(x);
	    }
	    pushup(x);
	}
	inline void access(int num)//将num和根节点连一条实边 
	{
		for(int y=0;num;num=fa[y=num])
		{
			splay(num);
			son[num][1]=y;
			pushup(num);
		}
	}
	inline void makeroot(int num)//换根 
	{
		access(num);
		splay(num);
		rever(num);
	}
	int findroot(int x)//找实际树上的根 
	{
		access(x);
		splay(x);
		while(son[x][0])pushdown(x),x=son[x][0];
		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)//将x和y连接(树上的连接) 
	{
		makeroot(x);
		if(findroot(y)!=x)fa[x]=y;
	}
	inline void cut(int x,int y)//将x和y断开(树上的断开),可以判断是否存在这条边 
	{
		makeroot(x);
	    if(findroot(y)==x&&fa[y]==x&&!son[y][0])
		{
	        fa[y]=son[x][1]=0;
	        pushup(x);
	    }
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值