社区讨论

LCT T飞求助

P2147[SDOI2008] 洞穴勘测参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi869xuv
此快照首次捕获于
2025/11/21 09:19
4 个月前
此快照最后确认于
2025/11/21 09:19
4 个月前
查看原帖
RT
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=10005;
int N,M;
struct LCT{
	int ch[maxn][2],fa[maxn];bool rev[maxn];
	int s[maxn],top;
	int Chk(int x){
		return x==ch[fa[x]][1];
	}
	bool Root(int x){
		return x!=ch[fa[x]][0]&&x!=ch[fa[x]][1];
	}
	void Push(int x){
		if(rev[x]){
			rev[x]^=1;
			rev[ch[x][0]]^=1;
			rev[ch[x][1]]^=1;
			swap(ch[x][0],ch[x][1]);
		}
	}
	void Rotate(int x){
		int y=fa[x],z=fa[y],k=Chk(x),w=ch[x][k^1];
		if(!Root(y))ch[z][Chk(y)]=x;fa[x]=z;
		ch[x][k^1]=y;fa[y]=x;
		ch[y][k]=w;fa[w]=y;
	}
	void Splay(int x){
		top=1;s[top]=x;
		for(int i=x;!Root(i);i=fa[i])s[++top]=fa[i];
		for(int i=top;i;i--)Push(s[top]);
		while(!Root(x)){
			int y=fa[x],z=fa[y];
			if(!Root(y)){
				if(Chk(x)==Chk(y))Rotate(y);
				else Rotate(x);
			}Rotate(x);
		}
	}
	void Access(int x){
		int k=0;
		while(x){
			Splay(x);
			ch[x][1]=k;
			k=x;
			x=fa[x];
		}
	}
	void Makeroot(int x){
		Access(x);
		Splay(x);
		rev[x]^=1;
	}
	void Split(int x,int y){
		Makeroot(x);
		Access(y);
		Splay(y);
	}
	void Link(int x,int y){
		Makeroot(x);
		fa[x]=y;
	}
	void Cut(int x,int y){
		Split(x,y);
		if(ch[y][0]==x&&!ch[x][1])
		fa[x]=ch[y][0]=0;
	}
	int Find(int x){
		Access(x);
		Splay(x);
		while(ch[x][0])x=ch[x][0];
		return x;
	}
}T;
void read(int &x){
    x=0;int f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    x*=f;
}
int main(){
	read(N);read(M);
	char s[10];int i,j;
	while(M--){
		scanf("%s",s);
		read(i);read(j);
		if(s[0]=='Q'){
			if(T.Find(i)==T.Find(j))printf("Yes\n");
			else printf("No\n");
		}else if(s[0]=='D')T.Cut(i,j);
		else T.Link(i,j);
	}
	return 0;
} 

回复

2 条回复,欢迎继续交流。

正在加载回复...