/* bzoj 3674: 可持久化并查集加强版 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 用可持久化线段树维护可持久化数组从而实现可持久化并查集 可持久化线段树+并查集+路径压缩+读入优化 */ #include <cstdio> #include <algorithm> using namespace std; const int Nmax=200005; int root_fa[Nmax]; inline 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; } struct Node { int ls; int rs; int data; }; Node fa[40*Nmax]; int n,m,ans,a,b,k; int size_fa; void build_fa(int &root,int l,int r) { root=size_fa++; int mid=(l+r)>>1; if(l==r) { fa[root].data=l; return; } build_fa(fa[root].ls,l,mid); build_fa(fa[root].rs,mid+1,r); } void insert_fa(int last,int &root,int pos,int data,int l,int r) { fa[size_fa]=fa[last]; root=size_fa; size_fa++; if(fa[root].ls==fa[root].rs) { // printf("root:%d,l:%d,data:%d ",root,fa[root].l,data); fa[root].data=data; return; } int mid=(l+r)>>1; if(pos<=mid) insert_fa(fa[last].ls,fa[root].ls,pos,data,l,mid); else insert_fa(fa[last].rs,fa[root].rs,pos,data,mid+1,r); } int search_fa(int root,int pos,int l,int r) { if(fa[root].ls==fa[root].rs) return fa[root].data; int mid=(l+r)>>1; if(pos<=mid) return search_fa(fa[root].ls,pos,l,mid); else return search_fa(fa[root].rs,pos,mid+1,r); } int find(int i,int x) { // if(x==0) // printf("error!!!! "); int fa=search_fa(root_fa[i],x,1,n); if(fa==x) return fa; int t=find(i,fa); insert_fa(root_fa[i],root_fa[i],fa,t,1,n); return t; } void watch(int root,int l,int r) { if(l==r) { printf("fa[%d]=%d ",l,fa[root].data); return; } int mid=(l+r)>>1; watch(fa[root].ls,l,mid); watch(fa[root].rs,mid+1,r); } int main() { // freopen("bzoj3674.in","r",stdin); //scanf("%d%d",&n,&m); n=read(); m=read(); ans=0; int q; build_fa(root_fa[0],1,n); // printf("the 0 watch: "); // watch(root_fa[0],1,n); for(int i=1;i<=m;i++) { //scanf("%d",&q); q=read(); if(q==1) { a=read(); b=read(); // scanf("%d%d",&a,&b); a^=ans;b^=ans; int rt1=find(i-1,a),rt2=find(i-1,b); // printf("root[%d]=%d,root[%d]=%d ",a,rt1,b,rt2); if(rt1==rt2) root_fa[i]=root_fa[i-1]; else insert_fa(root_fa[i-1],root_fa[i],rt1,rt2,1,n); // printf("search_fa[2]=%d ",search_fa(root_fa[1],2) ); // printf("root[%d]=%d,root[%d]=%d ",a,find(root_fa[i],a),b,find(root_fa[i],b)); } else if(q==2) { k=read(); // scanf("%d",&k); k^=ans; root_fa[i]=root_fa[k]; } else if(q==3) { a=read(); b=read(); // scanf("%d%d",&a,&b); root_fa[i]=root_fa[i-1]; a^=ans; b^=ans; if(find(i,a)==find(i,b)) ans=1; else ans=0; printf("%d ",ans); } //insert_fa(root_fa[i-1],root_fa[i],2,3); // printf("root_fa[%d]:%d ",i,root_fa[i]); // printf("the %d watch: ",i); // watch(root_fa[i],1,n); } return 0; }