/*
BZOJ 3674: 可持久化并查集加强版
主席树+并查集
*/
#include <cstdio>
#include <algorithm>
#define m (l+r)/2
using namespace std;
const int N = 200100;
const int M = N * 60;
int n,q,tot;
int fa[M],dp[M],T[N*4],lson[M],rson[M];
int init(int l,int r){
int root=tot++;
if(l==r)fa[root]=l,dp[root]=0;
else lson[root]=init(l,m),rson[root]=init(m+1,r);
return root;
}
int read(){
int x=0;char ch=getchar();
while(ch>'9'||ch<'0')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
int upd(int root,int pos,int val,int tag){//printf("%d%d%d\n",tag,pos,val);
int l=1,r=n,ret=tot++,cur=ret;
while(r>l){
if(pos<=m){
r=m;
rson[cur]=rson[root];
cur=lson[cur]=tot++;
root=lson[root];
}
else{
l=m+1;
lson[cur]=lson[root];
cur=rson[cur]=tot++;
root=rson[root];
}
}
fa[cur]=fa[root];dp[cur]=dp[root];
if(tag==0)fa[cur]=val;
else dp[cur]=val;
return ret;
}
int get(int root,int pos,int tag){
int l=1,r=n;
while(r>l){
if(pos<=m)r=m,root=lson[root];
else l=m+1,root=rson[root];
}
if(tag)return dp[root];
return fa[root];
}
int get_fa(int root,int pos){
int tmp=pos;
while((tmp=get(root,tmp,0))!=pos)pos=tmp;
return tmp;
}
int main(){
while(~scanf("%d%d",&n,&q))
{
tot=0;
T[0]=init(1,n);
int ans=0;
for(int i=1;i<=q;i++){
int p,a,b; //b=1;
p=read();a=read();
if(p==2){
a^=ans;
T[i]=T[a];
}
if(p==1){
b=read();
a^=ans;b^=ans;
T[i]=T[i-1];
int fa=get_fa(T[i],a),fb=get_fa(T[i],b);
if(fa!=fb){
int dpa=get(T[i],fa,1),dpb=get(T[i],fb,1);
if(dpa<dpb)swap(dpa,dpb),swap(fa,fb);
T[i]=upd(T[i],fb,fa,0);
if(dpa==dpb)T[i]=upd(T[i],fa,dpa+1,1);
}
}
if(p==3){
b=read();
a^=ans;b^=ans;
T[i]=T[i-1];
ans=(get_fa(T[i],a)==get_fa(T[i],b));
printf("%d\n",ans);
}
}
}
}
BZOJ 3674 主席树+并查集
最新推荐文章于 2019-07-04 21:47:18 发布