【BZOJ3674】—可持久化并查集加强版(可持久化并查集)
我还以为可持久化并查集是什么呢
可持久化并查集可持久化并查集主席树并查集
考虑到每次状态只会修改一个集合
于是就想可持久化数组一样
维护一颗主席树来维护每个点的
#include<bits/stdc++.h>
using namespace std;
#define gc getchar
#define ll long long
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=gc();}
while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48),ch=gc();}
return res*f;
}
#undef gc
const int N=200005;
const int Log=30;
int lc[N*Log],rc[N*Log],fa[N*Log],dep[N*Log],n,m,tot,rt[N*Log];
#define mid ((l+r)>>1)
void buildtree(int &u,int l,int r){
u=++tot;
if(l==r){fa[u]=l;return;}
buildtree(lc[u],l,mid),buildtree(rc[u],mid+1,r);
}
void merge(int pre,int &u,int l,int r,int pos,int f){
u=++tot,lc[u]=lc[pre],rc[u]=rc[pre];
if(l==r){
fa[u]=f,dep[u]=dep[pre];return;
}
if(pos<=mid)merge(lc[pre],lc[u],l,mid,pos,f);
else merge(rc[pre],rc[u],mid+1,r,pos,f);
}
void update(int u,int l,int r,int pos){
if(l==r){dep[u]++;return;}
if(pos<=mid)update(lc[u],l,mid,pos);
else update(rc[u],mid+1,r,pos);
}
int query(int u,int l,int r,int pos){
if(l==r)return u;
if(pos<=mid)return query(lc[u],l,mid,pos);
else return query(rc[u],mid+1,r,pos);
}
int find(int u,int pos){
int now=query(u,1,n,pos);
if(fa[now]==pos)return now;
return find(u,fa[now]);
}
int main(){
n=read(),m=read();
buildtree(rt[0],1,n);
for(int i=1;i<=m;i++){
int op=read(),x=read();
if(op==1){
rt[i]=rt[i-1];
int y=read();
int f1=find(rt[i],x),f2=find(rt[i],y);
if(fa[f1]!=fa[f2]){
if(dep[f1]>dep[f2])swap(f1,f2);
merge(rt[i-1],rt[i],1,n,fa[f1],fa[f2]);
if(dep[f1]==dep[f2])update(rt[i],1,n,fa[f2]);
}
}
else if(op==2)rt[i]=rt[x];
else if(op==3){
int y=read();
rt[i]=rt[i-1];
int f1=find(rt[i],x),f2=find(rt[i],y);
if(fa[f1]==fa[f2])puts("1");
else puts("0");
}
}
}