洛谷P2147 [SDOI2008] 洞穴勘测

P2147 [SDOI2008] 洞穴勘测

一看动态维护图连通性,吓到我了,还以为是那个黑题板子。

但原题目中有这样一句话

经过长期的艰苦卓绝的手工推算,辉辉发现一个奇怪的现象:无论通道怎么改变,任意时刻任意两个洞穴之间至多只有一条路径。

于是这便是一棵树了。

于是大力LCT。

完了。

#include<iostream>
using namespace std;
const int N = 1e5+100;
struct node{
	int fa,son[2],val,sum,lazy;
}T[N];
inline void swap(int &x,int &y){
	int tmp = x;
	x = y,y = tmp;
}
bool Isroot(int u){
	int f = T[u].fa;
	return T[f].son[0]!=u && T[f].son[1]!=u;
}
void Pushup(int u){
	T[u].sum = T[u].val ^ T[T[u].son[0]].sum ^ T[T[u].son[1]].sum;
}
void Reverse(int u){
	if(!u) return;
	swap(T[u].son[0],T[u].son[1]);
	T[u].lazy ^= 1;
}
void Pushdown(int u){
	if(T[u].lazy){
		Reverse(T[u].son[0]),Reverse(T[u].son[1]);
		T[u].lazy = 0;
	}
}
void Push(int u){
	if(!Isroot(u)) Push(T[u].fa);
	Pushdown(u);
}
void Rotate(int u){
	int f = T[u].fa,g = T[T[u].fa].fa;
	int lorr = (T[f].son[1] == u);
	//祖父与当前节点连边 
	if(!Isroot(f)) T[g].son[T[g].son[1]==f] = u;
	T[u].fa = g;
	//父亲与当前节点的儿子连边 
	T[f].son[lorr] = T[u].son[lorr^1];
	if(T[u].son[lorr^1]) T[T[u].son[lorr^1]].fa = f;
	//父亲与当前节点连边 
	T[u].son[lorr^1] = f;
	T[f].fa = u;
	Pushup(f);
}
void Splay(int u){
	Push(u);
	while(!Isroot(u)){
		int f = T[u].fa,g = T[T[u].fa].fa;
		if(!Isroot(f)) Rotate(((T[f].son[1]==u)==(T[g].son[1]==f))?f:u);
		Rotate(u);
	}
	Pushup(u);
}
void Access(int u){
	int child = 0;
	while(u){
		Splay(u);
		T[u].son[1] = child;
		Pushup(u);
		child = u,u = T[u].fa;
	}
}
void Makeroot(int u){
	Access(u),Splay(u),Reverse(u);
}
void Split(int u,int v){
	Makeroot(u),Access(v),Splay(v);
}
void Link(int u,int v){
	Makeroot(u),T[u].fa = v;
}
void Cut(int u,int v){
	Split(u,v);
	if(T[v].son[0]!=u or T[u].son[1]) return;
	T[u].fa = T[v].son[0] = 0;
	Pushup(v);
}
int Findroot(int u){
	Access(u),Splay(u);
	while(T[u].son[0]) Pushdown(u),u = T[u].son[0];
	return u;
}
int n,m,x,y;
string op;
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>op>>x>>y;
		if(op=="Query") cout<<(Findroot(x)==Findroot(y)?"Yes":"No")<<'\n';
		if(op=="Connect"){
			if(Findroot(x)!=Findroot(y)) Link(x,y);
		}
		if(op=="Destroy") Cut(x,y);
	}
	return 0;
}
posted @ 2025-03-23 22:32  OrangeRED  阅读(29)  评论(0)    收藏  举报