对于link的一些疑问(含第一组数据)
查看原帖
对于link的一些疑问(含第一组数据)
1175391
lin20081016楼主2025/1/26 15:52
bool link(int x,int y){
	mkrt(x);
	if(fdrt(y)==x)return 0;
	mkrt(y);//不加这一行就WA了
	t[x].fa=y;
	t[y].SIZ+=t[x].siz;
	return 1;
}

与普通的LCT相比,这题的link似乎要多加上一句makeroot(x),不然全WA评测记录。但原模板对于其他题目都适用,不知道是这题特殊原因,还是其他题目没hack掉模板?

附第一组数据和代码。

P4219_1.in:
10 20
A 4 10
A 1 6
A 10 1
Q 4 10
A 9 8
A 7 9
Q 10 1
A 2 5
Q 9 8
Q 2 5
Q 4 10
Q 9 8
Q 2 5
A 8 3
Q 7 9
Q 2 5
A 5 7
Q 8 3
A 3 4
Q 7 9

P4219_1.out:
3
4
2
1
3
2
1
3
1
5
21

错误输出:
3
4
2
1
3
2
1
3
1
3
15
代码同第二篇hsfzLZH1题解思路
#include<bits/stdc++.h>
#define N 100010
using namespace std;
struct s{int siz,SIZ,fa,son[2];bool r;}t[N];
//siz:总子树节点数 SIZ:虚儿子子树节点数
int n,m,x,y;
char c;
int id(int x){return t[t[x].fa].son[1]^x?(t[t[x].fa].son[0]^x?-1:0):1;}
//结合get和isroot
void rev(int x){if(x)t[x].r^=1,swap(t[x].son[0],t[x].son[1]);}
void pd(int x){if(t[x].r)rev(t[x].son[0]),rev(t[x].son[1]),t[x].r=0;}
void pu(int x){t[x].siz=t[x].SIZ+t[t[x].son[0]].siz+t[t[x].son[1]].siz+1;}
void upd(int x){if(id(x)^-1)upd(t[x].fa);pd(x);}
void rot(int x){
	int y=t[x].fa,z=t[y].fa,idx=id(x),idy=id(y);
	if(t[x].son[idx^1])t[t[x].son[idx^1]].fa=y;t[y].son[idx]=t[x].son[idx^1];
	t[y].fa=x;t[x].son[idx^1]=y;
	t[x].fa=z;if(idy^-1)t[z].son[idy]=x;
	pu(y),pu(x);
}
void splay(int x){
	upd(x);
	int idx,idy,y;
	while((idx=id(x))^-1){if((idy=id(y=t[x].fa))^-1){rot(idx^idy?x:y);}rot(x);}
}
int lkrt(int x){//access
	int w=0;
	while(x){
		splay(x);
		t[x].SIZ+=t[t[x].son[1]].siz-t[w].siz;
		t[x].son[1]=w;
		pu(x);
		x=t[w=x].fa;
	}
	return w;
}
void mkrt(int x){//makeroot
	lkrt(x);
	splay(x);
	rev(x);
}
int fdrt(int x){//findroot
	lkrt(x);
	splay(x);
	while(pd(x),t[x].son[0])x=t[x].son[0];
	splay(x);
	return x;
}
void spl(int x,int y){//split
	mkrt(x);
	lkrt(y);
	splay(y);
}
bool link(int x,int y){
	mkrt(x);
	if(fdrt(y)==x)return 0;
	mkrt(y);//关键一招
	t[x].fa=y;
	t[y].SIZ+=t[x].siz;
	return 1;
}
bool cut(int x,int y){
	mkrt(x);
	if(fdrt(y)^x||t[y].fa^x||t[y].son[0])return 0;
	t[y].fa=t[x].son[1]=0;
	pu(x);
	return 1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("\n%c%d%d",&c,&x,&y);
		if(c=='A'){
			link(x,y);
		}else{
			spl(x,y);
			cut(x,y);
			mkrt(x),mkrt(y);
			printf("%lld\n",(long long)t[x].siz*t[y].siz);
			link(x,y);
		}
	}
}
2025/1/26 15:52
加载中...