【BZOJ2049】【SDOI2008】Cave 洞穴勘测 LCT裸题 模版题 数组版

数组,至少目前我只写数组,不写指针。


LCT这种东西我不打算讲或者什么乱七八糟的,反正这一篇是自用。

同样,看这篇博客的人可以先去别的地方学LCT,然后来我这扒代码。


代码:

#include 
#include 
#include 
#include 
#define ls son[x][0]
#define rs son[x][1]
#define is(x) (x==son[fa[x]][1])
#define isroot(x) (x!=son[fa[x]][0]&&x!=son[fa[x]][1])
#define N 10010
#define inf 0x3f3f3f3f
using namespace std;
int pos[N],n,m;
char ttt[10];
struct LCT
{
	int son[N][2],fa[N],cnt;
	bool flag[N];
	int stack[N],top;
	void joint(int x,int y,int d){fa[x]=y,son[y][d]=x;}
	void reverse(int x)
	{
		flag[x]^=1;
		swap(ls,rs);
	}
	void pushdown(int x)
	{
		if(flag[x])
		{
			reverse(x);
			flag[ls]^=1,flag[rs]^=1;
			flag[0]=0;
		}
	}
	int newnode()
	{
		cnt++;
		son[cnt][0]=son[cnt][1]=fa[cnt]=0;
		return cnt;
	}
	void pushpath(int x)
	{
		for(top=0;!isroot(x);x=fa[x])stack[++top]=x;
		stack[++top]=x;
		for(int i=top;i;i--)pushdown(stack[i]);
	}
	void rotate(int x)
	{
		int y=fa[x],z=fa[y],i=is(x),t=son[x][!i];
		if(!isroot(y))joint(x,z,is(y));
		else fa[x]=z;
		joint(t,y,i),joint(y,x,!i);
		fa[0]=son[0][0]=son[0][1]=0;
	}
	void splay(int x)
	{
		pushpath(x);
		int y,z;
		while(!isroot(x))
		{
			y=fa[x],z=fa[y];
			if(isroot(y)){rotate(x);break;}
			rotate(is(x)==is(y)?y:x),rotate(x);
		}
	}
	void access(int x)
	{
		int p=0;
		while(x)
		{
			splay(x);
			rs=p,p=x,x=fa[x];
		}
	}
	void makeroot(int x)
	{
		access(x);
		splay(x);
		flag[x]=1;
		pushdown(x);
	}
	void link(int x,int y)
	{
		makeroot(x);
		fa[x]=y;
	}
	void cut(int x,int y)
	{
		makeroot(y);
		access(x);
		splay(x);
		ls=fa[y]=0;
	}
	int findroot(int x)
	{
		while(fa[x])x=fa[x];
		return x;
	}
}lct;

int main()
{
//	freopen("test.in","r",stdin);
	int i,a,b;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)pos[i]=lct.newnode();
	for(i=1;i<=m;i++)
	{
		scanf("%s",ttt);
		scanf("%d%d",&a,&b);
		if(ttt[0]=='C')lct.link(pos[a],pos[b]);
		else if(ttt[0]=='D')lct.cut(pos[a],pos[b]);
		else 
		{
			if(lct.findroot(pos[a])==lct.findroot(pos[b]))puts("Yes");
			else puts("No");
		}		
	}
	return 0;
}


你可能感兴趣的:(LCT,模板)