对于并查集数组fa[i],可以拿可持久化线段树来维护
好像要按秩合并才能过吧
/**************************************************************
Problem: 3674
User: di4CoveRy
Language: C++
Result: Accepted
Time:1748 ms
Memory:98196 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#define mid ((l+r)>>1)
#define N 200050
using namespace std;
int x,v,n,m;
struct hyy_tree{
int tr[20*N],num[N],h[N],ls[20*N],rs[20*N],cnt,rt;
int build(int l,int r,int &t) {
if (!t) t = ++cnt;
if (l == r) return tr[t] = num[l];
build(l,mid,ls[t]); build(mid+1,r,rs[t]);
}
void ins(int l,int r,int las,int &t) {
if (!t) t = ++cnt;
if (l == r) { tr[t] = v; return ; }
if (x <= mid)
ins(l,mid,ls[las],ls[t]) , rs[t] = rs[las];
else
ins(mid+1,r,rs[las],rs[t]),ls[t] = ls[las];
}
int query(int l,int r,int t) {
if (l == r) return tr[t];
if (x <= mid)
return query(l,mid,ls[t]);
else
return query(mid+1,r,rs[t]);
}
int ask(int w,int his) {
x = w; return query(1,n,his);
}
}fa,siz;
int get(int u) {
int cur = fa.ask(u,fa.rt);
if (cur == u) return cur; else return get(cur);
}
int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) fa.num[i] = i , siz.num[i] = 1;
fa.build(1,n, fa.h[0]);
siz.build(1,n,siz.h[0]);
fa.rt = fa.h[0];
siz.rt = siz.h[0];
int ans = 0;
for (int _=1;_<=m;_++) {
int cmd=0; scanf("%d",&cmd);
if (cmd == 1) {
int a,b; scanf("%d%d",&a,&b);
a ^= ans; b ^= ans;
int p = get(a) , q = get(b);
int pp = siz.ask(p,siz.rt) , qq = siz.ask(q,siz.rt);
if (p == q) continue;
if (pp < qq) swap(p,q);
x = q , v = p;
fa.ins(1,n, fa.rt, fa.h[_]);
fa.rt = fa.h[_];
x = p , v = pp+qq;
siz.ins(1,n,siz.rt,siz.h[_]);
siz.rt = siz.h[_];
}
if (cmd == 2) {
int k=0; scanf("%d",&k);
k ^= ans;
fa.h[_] = fa.rt = fa.h[k];
siz.h[_] = siz.rt = siz.h[k];
}
if (cmd == 3) {
int a=0,b=0; scanf("%d%d",&a,&b);
a ^= ans , b ^= ans;
int p = get(a) , q = get(b);
ans = p == q;
printf("%d\n",ans);
fa.h[_] = fa.rt;
siz.h[_] = siz.rt;
}
}
return 0;
}