题目链接
思路
用可持久化数组维护历史版本的 fa
父亲数组和 dep
树深度数组,以树深按秩合并。
代码
#include <stdio.h>
const int maxn = 2e5+5;
int n, m;
struct Node
{
int l, r, val;
}h[maxn*80];
int cnt, rootfa[maxn], rootdep[maxn], tot;
void build(int l, int r, int &now) {
now = ++cnt;
if(l == r) {
h[now].val = ++tot;
return;
}
int mid = l+r >> 1;
build(l,mid,h[now].l);
build(mid+1,r,h[now].r);
}
void modify(int l, int r, int ver, int &now, int pos, int val) {
h[now = ++cnt] = h[ver];
if(l == r) {
h[now].val = val;
return;
}
int mid = l+r >> 1;
if(pos <= mid) modify(l,mid,h[ver].l,h[now].l,pos,val);
else modify(mid+1,r,h[ver].r,h[now].r,pos,val);
}
int query(int l, int r, int now, int pos) {
if(l == r) return h[now].val;
int mid = l+r >> 1;
if(pos <= mid) return query(l,mid,h[now].l,pos);
return query(mid+1,r,h[now].r,pos);
}
int getf(int now, int x) {
int fx = query(1,n,rootfa[now],x);
return fx == x ? x : getf(now,fx);
}
void mer(int now, int x, int y) {
x = getf(now-1,x);
y = getf(now-1,y);
if(x == y) {
rootfa[now] = rootfa[now-1];
rootdep[now] = rootdep[now-1];
return;
}
int xdep = query(1,n,rootdep[now-1],x);
int ydep = query(1,n,rootdep[now-1],y);
if(xdep < ydep) {
modify(1,n,rootfa[now-1],rootfa[now],x,y);
rootdep[now] = rootdep[now-1];
}
else {
modify(1,n,rootfa[now-1],rootfa[now],y,x);
if(xdep == ydep) modify(1,n,rootdep[now-1], rootdep[now],x,xdep+1);
else rootdep[now] = rootdep[now-1];
}
}
int main() {
scanf("%d%d",&n,&m);
build(1,n,rootfa[0]);
for(int i = 1; i <= m; ++i) {
int opt, a, b;
scanf("%d",&opt);
if(opt == 1) {
scanf("%d%d",&a,&b);
mer(i,a,b);
}
else if(opt == 2) {
scanf("%d",&a);
rootfa[i] = rootfa[a];
rootdep[i] = rootdep[a];
}
else {
scanf("%d%d",&a,&b);
rootfa[i] = rootfa[i-1];
rootdep[i] = rootdep[i-1];
puts(getf(i,a) == getf(i,b) ? "1" : "0");
}
}
return 0;
}