洞穴勘测——LCT模板

改了4小时,我果然还是太弱了……

#include<bits/stdc++.h>
using namespace std;
const int maxx=1e4+5;
int c[maxx][2],fa[maxx],Rev[maxx];
int get(int x){
    if(c[fa[x]][1]==x)return 1;
    if(c[fa[x]][0]==x)return 0;
    return -1;
}void rot(int x){
 int f=fa[x],ff=fa[f],l=get(x),r=l^1;
    if(get(f)!=-1)c[ff][c[ff][1]==f]=x;
    fa[c[x][r]]=f; fa[f]=x; fa[x]=ff; 
    c[f][l]=c[x][r]; c[x][r]=f; 
}
 
void pushdown(int x){
	if(Rev[x]){
		Rev[x]=0;
		swap(c[x][0],c[x][1]);
		Rev[c[x][0]]^=1;
		Rev[c[x][1]]^=1;
	}
}
void cle(int x){if(get(x)!=-1)cle(fa[x]);pushdown(x);}
void splay(int x){
    cle(x);
    for(int f=fa[x];get(x)!=-1;rot(x),f=fa[x])
        if(get(f)!=-1)rot(get(x)==get(f)?f:x);
}
void Access(int x){for(int t=0;x;x=fa[t=x])splay(x),c[x][1]=t;}
int Findroot(int x){//找x结点的根 
	Access(x);
	splay(x);
	while(c[x][0]){
		pushdown(x);
		x=c[x][0];
	} 
	return x;
} 
int Evert(int x){//反转X到根的链 
	Access(x);
	splay(x);
	Rev[x]=1;
}
void Cut(int x,int y){
	Evert(x);
	Access(y);
	splay(y);
	fa[x]=c[y][0]=0;
}
void Link(int x,int y){//让x成为y的新儿子 ,注意x是一个根 
	Evert(y);
	fa[y]=x;
}
int main(){
	char ch[20];
	int x,y,n,m;
	scanf("%d%d",&n,&m);
	while(m--){
		scanf("%s%d%d",ch,&x,&y);
		if(ch[0]=='C')Link(x,y);
		if(ch[0]=='D')Cut(x,y);
		if(ch[0]=='Q'){
			if(Findroot(x)==Findroot(y))printf("Yes\n");
			else printf("No\n");
		}
	}
	return 0;
}

  

转载于:https://www.cnblogs.com/wyb-----520/p/10122623.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值