可持久化并查集模板
#include<bits/stdc++.h> using namespace std; const int MAXN=1e6+2333; int n,m; int a[MAXN]; struct Persistable_Segment_Tree{ struct Node{ int val,L,R,dep; }t[MAXN*20]; int cnt,rt[MAXN*20]; void build_tree(int &root,int l,int r){ root=++cnt; if (l==r) return (void)(t[root].val=l,t[root].dep=1); int mid=l+r>>1; build_tree(t[root].L,l,mid); build_tree(t[root].R,mid+1,r); } void update(int &root,int las,int l,int r,int q,int opt){ root=++cnt; t[root]=t[las]; if (l==r) return (void)(t[root].val=opt); int mid=l+r>>1; if (q<=mid) update(t[root].L,t[las].L,l,mid,q,opt); else update(t[root].R,t[las].R,mid+1,r,q,opt); } void add_deep(int root,int l,int r,int q){ if (l==r) return (void)(t[root].dep++); int mid=l+r>>1; if (q<=mid) add_deep(t[root].L,l,mid,q); else add_deep(t[root].R,mid+1,r,q); } int query(int root,int l,int r,int q){ if (l==r) return root; int mid=l+r>>1; if (q<=mid) return query(t[root].L,l,mid,q); else return query(t[root].R,mid+1,r,q); } }T; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)){ if (ch=='-') f=-1; ch=getchar(); } while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f; } int find(int &rt,int x){ int tmp=T.query(rt,1,n,x); while (x!=T.t[tmp].val) x=T.t[tmp].val,tmp=T.query(rt,1,n,x); return tmp; } int main(){ n=read(),m=read(); T.cnt=0,T.build_tree(T.rt[0],1,n); int opt,x,y,u,v,dep_x,dep_y; for (int i=1;i<=m;i++){ opt=read(); if (opt==1){ // 合并集合 x=find(T.rt[i-1],read()),y=find(T.rt[i-1],read()); u=T.t[x].val,v=T.t[y].val; dep_x=T.t[x].dep,dep_y=T.t[y].dep; if (u!=v){ if (dep_x>dep_y) swap(u,v); T.update(T.rt[i],T.rt[i-1],1,n,u,v); if (dep_x==dep_y) T.add_deep(T.rt[i],1,n,v); } else T.rt[i]=T.rt[i-1]; } else if (opt==2){ // 回到历史版本 x=read(); T.rt[i]=T.rt[x]; } else if (opt==3){ //查询是否在同一集合 x=find(T.rt[i-1],read()),y=find(T.rt[i-1],read()); T.rt[i]=T.rt[i-1]; printf("%d\n",x!=y ? 0:1); } } return 0; }