可持久化数组
可持久化数组是一种可以回退,访问之前版本的数组
是一些其他可持久化数据结构的基石
例如可持久化并查集)
与普通并查集不同的是 这里用到了 按秩合并
不了解可以百度一下
添加链接描述
#include <stdio.h>
const int N = 2e5 + 7;
int rootfa[N], rootdep[N], cnt, tot;
struct Node {
int l, r, val;
} T[N*40*2];
int n;
void insert(int l, int r, int &now) {
now = ++ cnt;
if (l == r) {
T[now].val = ++ tot;
return;
}
int mid = l + r >> 1;
insert(l, mid, T[now].l);
insert(mid + 1, r, T[now].r);
}
void modify(int l, int r, int pre, int &now, int pos, int val) {
T[now = ++cnt] = T[pre];
if (l == r) {
T[now].val = val;
return;
}
int mid = l + r >> 1;
if (pos <= mid) modify(l, mid, T[pre].l, T[now].l, pos, val);
else modify(mid + 1, r, T[pre].r, T[now].r, pos, val);
}
int query(int l, int r, int now, int pos) {
if (l == r) return T[now].val;
int mid = l + r >> 1;
if (pos <= mid) return query(l, mid , T[now].l, pos);
else return query(mid + 1, r, T[now].r, pos);
}
int find(int ver, int x) {
int fx = query(1, n, rootfa[ver], x);
return fx == x ? x : find(ver, fx);
}
void merge(int ver, int x, int y) {
x = find(ver - 1, x);
y = find(ver - 1, y);
if (x == y) {
rootfa[ver] = rootfa[ver-1];
rootdep[ver] = rootdep[ver-1];
} else {
int depx = query(1, n, rootdep[ver-1], x);
int depy = query(1, n, rootdep[ver-1], y);
if (depx < depy) {
modify(1, n, rootfa[ver-1], rootfa[ver], x, y);
rootdep[ver] = rootdep[ver-1];
} else if (depx > depy) {
modify(1, n, rootfa[ver-1], rootfa[ver], y, x);
rootdep[ver] = rootdep[ver-1];
} else {
modify(1, n, rootfa[ver-1], rootfa[ ver], y, x);
modify(1, n, rootdep[ver-1], rootdep[ver], x, depx + 1);
}
}
}
int main () {
int m, opt, x, y;
scanf ("%d%d", &n, &m);
insert(1, n, rootfa[0]);
for (int i = 1; i <= m; i ++ ) {
scanf ("%d", &opt);
switch(opt) {
case 1: {
scanf ("%d%d", &x, &y);
merge(i, x, y);
break;
}
case 2: {
scanf ("%d", &x);
rootfa[i] = rootfa[x];
rootdep[i] = rootdep[x];
break;
}
case 3: {
scanf ("%d%d", &x, &y);
rootfa[i] = rootfa[i-1];
rootdep[i] = rootdep[i-1];
int a = find(i,x);
int b = find(i,y);
printf ("%d\n", a == b ? 1 : 0);
break;
}
}
}
return 0;
}