【模板】可持久化并查集

可持久化并查集

性质

可持久化并查集 = 可持久化数组 + 并查集 = 主席树 + 并查集
时间复杂度 \(O(n log^2 n)\)

\(Code\)

#include<cstdio>
#include<iostream>
using namespace std;

const int N = 2e5 + 5;
int n, m, cnt, fa[N * 32], dep[N * 32], rt[N];
struct node{int ls, rs;}tr[N * 32];

inline void read(int &x)
{
	x = 0; int f = 1; char ch = getchar();
	while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : f), ch = getchar();
	while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
	x *= f;
}

void build(int &p, int l, int r)
{
	p = ++cnt;
	if (l == r)
	{
		fa[p] = l;
		return;
	}
	int mid = (l + r) >> 1;
	build(tr[p].ls, l, mid);
	build(tr[p].rs, mid + 1, r);
}

void update(int &u, int v, int l, int r, int x, int y)
{
	u = ++cnt, tr[u] = tr[v];
	if (l == r)
	{
		fa[u] = y, dep[u] = dep[v];
		return;
	}
	int mid = (l + r) >> 1;
	if (x <= mid) update(tr[u].ls, tr[v].ls, l, mid, x, y);
	else update(tr[u].rs, tr[v].rs, mid + 1, r, x, y);
}

void Add(int p, int l, int r, int x)
{
	if (l == r)
	{
		++dep[p];
		return;
	}
	int mid = (l + r) >> 1;
	if (x <= mid) Add(tr[p].ls, l, mid, x);
	else Add(tr[p].rs, mid + 1, r, x);
}

int query(int p, int l, int r, int x)
{
	if (l == r) return p;
	int mid = (l + r) >> 1;
	if (x <= mid) return query(tr[p].ls, l, mid, x);
	else return query(tr[p].rs, mid + 1, r, x);
}

int find(int p, int x)
{
	int y = query(p, 1, n, x);
	if (fa[y] == x) return y;
	return find(p, fa[y]);
}

int main()
{
	read(n), read(m);
	build(rt[0], 1, n);
	for(register int i = 1, op, a, b; i <= m; i++)
	{
		read(op);
		if (op == 1)
		{
			rt[i] = rt[i - 1];
			read(a), read(b);
			int x = find(rt[i], a), y = find(rt[i], b);
			if (fa[x] == fa[y]) continue;
			if (dep[x] > dep[y]) swap(x, y);
			update(rt[i], rt[i - 1], 1, n, fa[x], fa[y]);
			if (dep[x] == dep[y]) Add(rt[i], 1, n, fa[y]);
		}
		else if (op == 2) read(a), rt[i] = rt[a];
		else{
			read(a), read(b);
			rt[i] = rt[i - 1];
			if (fa[find(rt[i], a)] != fa[find(rt[i], b)]) printf("0\n");
			else printf("1\n");
		}
	}
}
posted @ 2021-01-01 15:48  leiyuanze  阅读(105)  评论(0编辑  收藏  举报