【Link-Cut Tree】 TLE求调
查看原帖
【Link-Cut Tree】 TLE求调
401052
Endline楼主2022/2/7 16:31

RT

#include<bits/stdc++.h>
#define MAXN 100002
using namespace std;
inline int read()
{
	int f=1,w=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
	return f*w;
}
struct Link_Cut_Tree{
	int ch[MAXN][2],fa[MAXN],val[MAXN],tag[MAXN],laz[MAXN],num[MAXN];
	int stk[MAXN],top;
	void push_up(int x)
	{
		num[x]=num[ch[x][0]]^num[ch[x][1]]^val[x];
		return;
	}
	void push_down(int x)
	{
		int l=ch[x][0],r=ch[x][1];
		if(tag[x])
		{
			tag[l]^=1;tag[r]^=1;tag[x]^=1;
			swap(ch[x][0],ch[x][1]);
		}
		return;
	}
	bool isroot(int x)
	{
		return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
	}
	void rotate(int x)
	{
		int y=fa[x],z=fa[y],l,r;
		if(ch[y][0]==x)l=0;
		else l=1;
		r=l^1;
		if(!isroot(y))
			if(ch[z][0]==y)ch[z][0]=x;
			else ch[x][1]=x;
		fa[x]=z,fa[y]=x,fa[ch[x][r]]=y;
		ch[y][l]=ch[x][r];ch[x][r]=y;
		push_up(y);push_up(x);
		return;
	}
	void splay(int x)
	{
		top=1;stk[top]=x;
		for(int i=x;!isroot(i);i=fa[i])stk[++top]=fa[i];
		for(int i=top;i;i--)push_down(stk[i]);
		while(!isroot(x)){
            int y=fa[x],z=fa[y];
            if(!isroot(y))
			{
                if((ch[y][0]==x)^(ch[z][0]==y))rotate(x);
                else rotate(y);
            }
			rotate(x);
        }
		return;
	}
	void access(int x)
	{
		for(int p=0;x;p=x,x=fa[x])
		{
			splay(x);
			ch[x][1]=p;
			push_up(x);
		}
		return;
	}
	void makeroot(int x)
	{
		access(x);
		splay(x);
		tag[x]^=1;
		return;
	}
	int find(int x)
	{
		access(x);
		splay(x);
		while(ch[x][0])x=ch[x][0];
		return x;
	}
	void split(int x,int y)
	{
		makeroot(x);
		access(y);
		splay(y);
		return;
	}
	void link(int x,int y)
	{
		makeroot(x);
		fa[x]=y;
		return;
	}
	void cut(int x,int y)
	{
		split(x,y);
		if(ch[y][0]==x&&ch[x][1]==0)ch[y][0]=0,fa[x]=0;
		return;
	}
}tree;
int n,m;
int main()
{
//	freopen("P3690_1.in","r",stdin);
//	freopen("P3690_1.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n;i++)tree.val[i]=read(),tree.num[i]=tree.val[i];
	for(int i=1;i<=m;i++)
	{
		int opt=read(),x=read(),y=read(),xx,yy;
		switch(opt)
		{
			case 0:
				tree.split(x,y);
				printf("%d\n",tree.num[y]);
				break;
			case 1:
				xx=tree.find(x),yy=tree.find(y);
				if(xx!=yy)tree.link(x,y);
				break;
			case 2:
				xx=tree.find(x),yy=tree.find(y);
				if(xx==yy)tree.cut(x,y);
				break;
			case 3:
				tree.access(x);
				tree.splay(x);
				tree.val[x]=y;
				tree.push_up(x);
				break;
			default:
				break;
		}
	}
	return 0;
}

2022/2/7 16:31
加载中...