BZOJ2049

最裸的lct了吧= =,直接根据题目连边删边,然后判断一蛤2个点是否在同一棵splay中吧,抄了一份模板,以后慢慢理解,估计还要改。

#include
#include
#include
#define maxl 100010

using namespace std;

int n,m;
int fa[maxl],c[maxl][2],s[maxl];
bool rev[maxl];
char ss[10];

inline void prework()
{
	memset(c,0,sizeof(int)*(n+1)*2);
	memset(fa,0,sizeof(int)*(n+1));
	memset(s,0,sizeof(int)*(n+1));
	memset(rev,false,sizeof(bool)*(n+1));
}

inline bool isroot(int x)
{
	return c[fa[x]][0]!=x && c[fa[x]][1]!=x;
}

inline void pushdown(int x)
{
	int l=c[x][0],r=c[x][1];
	if(rev[x])
	{
		rev[x]^=1;rev[l]^=1;rev[r]^=1;
		swap(c[x][0],c[x][1]);
	}
}

inline void rotate(int x)
{
	int y=fa[x],z=fa[y];
	int l=(c[y][0]!=x),r=l^1;
	if(!isroot(y))
	{
		if(c[z][0]==y)
			c[z][0]=x;
		else
			c[z][1]=x;
	}
	fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
	c[y][l]=c[x][r],c[x][r]=y;
}

inline void splay(int x)
{
	int top=0;s[++top]=x;
	for(int i=x;!isroot(i);i=fa[i])
		s[++top]=fa[i];
	while(top>0)
	{
		pushdown(s[top]);
		top--;
	}
	while(!isroot(x))
	{
		int y=fa[x],z=fa[y];
		if(!isroot(y))
		{
			if((c[y][0]==x) ^(c[z][0]==y))
				rotate(x);
			else
				rotate(y);
		}
		rotate(x);
	}
}

inline void access(int x)
{
	for(int t=0;x;x=fa[x])
	{
		splay(x);
		c[x][1]=t;t=x;
	}
}

inline void makeroot(int x)
{
	access(x);splay(x);rev[x]^=1;
}

inline void link(int x,int y)
{
	makeroot(x);fa[x]=y;splay(x);
}

inline void cut(int x,int y)
{
	makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;
}

inline int find(int x)
{
	access(x);splay(x);
	int y=x;
	while(c[y][0])
		y=c[y][0];
	return y;
}

inline void mainwork()
{
	int x,y;
	for(int i=1;i<=m;i++)
	{
		scanf("%s",ss);
		scanf("%d%d",&x,&y);
		if(ss[0]=='C')
			link(x,y);
		if(ss[0]=='D')
			cut(x,y);
		if(ss[0]=='Q')
			puts(find(x)==find(y)?"Yes":"No");
	}
}

inline void print()
{
}

int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

你可能感兴趣的:(LCT)