可爱并查集求调,玄一关
  • 板块灌水区
  • 楼主_Cheems
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/10/26 14:06
  • 上次更新2023/11/2 11:21:35
查看原帖
可爱并查集求调,玄一关
514283
_Cheems楼主2023/10/26 14:06

RT,可持久化并查集写炸了,貌似是按秩合并写错了。代码还算能看,求调悬关

提交记录,难道是常数问题吗,QwQ

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5; 
int n, m, opt, a, b, fa;
int rot[N << 1];

namespace Segment_Tree{
	#define mid (l + r >> 1)
	
	int ls[N * 45], rs[N * 45], id[N * 45], dep[N * 45], tot;
	
	inline void to(int ua, int ub) {ls[ub] = ls[ua], rs[ub] = rs[ua], dep[ub] = dep[ua], id[ub] = id[ua];}
	inline void change(int &u, int l, int r, int k, int c, int flag){ //修改原有版本
		if(!u) u = ++tot;
		if(l == r){
			if(flag == 1) id[u] = c;
			else dep[u] = c;
			return ;
		}
		if(k <= mid) change(ls[u], l, mid, k, c, flag);
		else change(rs[u], mid + 1, r, k, c, flag);
	}
	inline void upd(int ua, int &ub, int l, int r, int k, int c, int flag){
		ub = ++tot, to(ua, ub);
		if(l == r){
			if(flag == 1) id[ub] = c;
			else dep[ub] = c;
			return ;
		}
		if(k <= mid) upd(ls[ua], ls[ub], l, mid, k, c, flag);
		else upd(rs[ua], rs[ub], mid + 1, r, k, c, flag);
	}
	inline int query(int u, int l, int r, int k, int flag){
		if(l == r) return flag == 1 ? id[u] : dep[u];
		if(k <= mid) return query(ls[u], l, mid, k, flag);
		else return query(rs[u], mid + 1, r, k, flag);
	}
}
using namespace Segment_Tree;
inline int find(int u, int hst){
	fa = query(rot[hst], 1, n, u, 1);
	return fa == u ? u : find(fa, hst);
}
inline void mer(int x, int y, int hst, int now){
	x = find(x, hst), y = find(y, hst);
	if(x == y){
		rot[now] = rot[hst];
		return ;
	}
	int sx = query(rot[hst], 1, n, x, 2), sy = query(rot[hst], 1, n, y, 2);
	if(sx > sy) swap(x, y), swap(sx, sy);
	upd(rot[hst], rot[now], 1, n, x, y, 1); //先创建新版本
	change(rot[now], 1, n, y, max(sy, sx + 1), 2); //再在这个版本上更改深度
}
signed main(){
	cin >> n >> m;
	for(int i = 1; i <= n;++i){
		change(rot[0], 1, n, i, i, 1);
		change(rot[0], 1, n, i, 1, 2);
	}
	for(int i = 1; i <= m;++i){
		scanf("%d%d", &opt, &a);
		if(opt == 2) rot[i] = rot[a];
		else{
			scanf("%d", &b);
			if(opt == 1) mer(a, b, i - 1, i);
			else{
				rot[i] = rot[i - 1];
				printf("%d\n", find(a, i) == find(b, i));
			}
		}
	}
	return 0;
}
2023/10/26 14:06
加载中...