1 /*
2 bzoj 3674: 可持久化并查集加强版
3 http://www.lydsy.com/JudgeOnline/problem.php?id=3674
4 用可持久化线段树维护可持久化数组从而实现可持久化并查集
5 可持久化线段树+并查集+按秩合并+读入优化
6 */
7 #include <cstdio>
8 #include <algorithm>
9 using namespace std;
10 const int Nmax=200005;
11 int root_fa[Nmax],root_rankk[Nmax];
12
13 inline int read()
14 {
15 int x=0;char ch=getchar();
16 while(ch>'9'||ch<'0')ch=getchar();
17 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
18 return x;
19 }
20 struct Node
21 {
22 int ls;
23 int rs;
24 int data;
25 };
26 Node fa[40*Nmax];
27 Node rankk[40*Nmax];
28 int n,m,ans,a,b,k;
29 int size_fa,size_rankk;
30
31 void build_rankk(int &root,int l,int r)
32 {
33 root=size_rankk++;
34 int mid=(l+r)>>1;
35 if(l==r)
36 {
37 rankk[root].data=0;
38 return;
39 }
40 build_rankk(rankk[root].ls,l,mid);
41 build_rankk(rankk[root].rs,mid+1,r);
42 }
43
44 void insert_rankk(int last,int &root,int pos,int l,int r)
45 {
46 rankk[size_rankk]=rankk[last];
47 root=size_rankk;
48 size_rankk++;
49 if(rankk[root].ls==rankk[root].rs)
50 {
51 rankk[root].data++;
52 return;
53 }
54 int mid=(l+r)>>1;
55 if(pos<=mid)
56 insert_rankk(rankk[last].ls,rankk[root].ls,pos,l,mid);
57 else
58 insert_rankk(rankk[last].rs,rankk[root].rs,pos,mid+1,r);
59 }
60
61 int search_rankk(int root,int pos,int l,int r)
62 {
63 if(rankk[root].ls==rankk[root].rs)
64 return rankk[root].data;
65 int mid=(l+r)>>1;
66 if(pos<=mid)
67 return search_rankk(rankk[root].ls,pos,l,mid);
68 else
69 return search_rankk(rankk[root].rs,pos,mid+1,r);
70 }
71
72 void build_fa(int &root,int l,int r)
73 {
74 root=size_fa++;
75 int mid=(l+r)>>1;
76 if(l==r)
77 {
78 fa[root].data=l;
79 return;
80 }
81 build_fa(fa[root].ls,l,mid);
82 build_fa(fa[root].rs,mid+1,r);
83 }
84
85 void insert_fa(int last,int &root,int pos,int data,int l,int r)
86 {
87 fa[size_fa]=fa[last];
88 root=size_fa;
89 size_fa++;
90 if(fa[root].ls==fa[root].rs)
91 {
92 // printf("root:%d,l:%d,data:%d\n",root,fa[root].l,data);
93 fa[root].data=data;
94 return;
95 }
96 int mid=(l+r)>>1;
97 if(pos<=mid)
98 insert_fa(fa[last].ls,fa[root].ls,pos,data,l,mid);
99 else
100 insert_fa(fa[last].rs,fa[root].rs,pos,data,mid+1,r);
101 }
102
103 int search_fa(int root,int pos,int l,int r)
104 {
105 if(fa[root].ls==fa[root].rs)
106 return fa[root].data;
107 int mid=(l+r)>>1;
108 if(pos<=mid)
109 return search_fa(fa[root].ls,pos,l,mid);
110 else
111 return search_fa(fa[root].rs,pos,mid+1,r);
112 }
113
114 int find(int root,int x)
115 {
116 // if(x==0)
117 // printf("error!!!!\n");
118 int fa=search_fa(root,x,1,n);
119 if(fa!=x)
120 return find(root,fa);
121 else
122 return fa;
123 }
124
125 // void watch(int root,int l,int r)
126 // {
127 // printf("tree[%d].l=%d,tree[%d].r=%d,tree[%d].data=%d\n",root,fa[root].l,root,fa[root].r,root,fa[root].data);
128 // if(l==r)
129 // return;
130 // int mid=(l+r)>>1;
131 // watch(fa[root].ls,l,mid);
132 // watch(fa[root].rs,mid+1,r);
133 // }
134
135 int main()
136 {
137 freopen("bzoj3674.in","r",stdin);
138 //scanf("%d%d",&n,&m);
139 n=read();
140 m=read();
141 ans=0;
142 int q;
143 build_fa(root_fa[0],1,n);
144 build_rankk(root_rankk[0],1,n);
145 // printf("the 0 watch:\n");
146 // watch(root_fa[0],1,n);
147 for(int i=1;i<=m;i++)
148 {
149 //scanf("%d",&q);
150 q=read();
151 if(q==1)
152 {
153 a=read();
154 b=read();
155 // scanf("%d%d",&a,&b);
156 a^=ans;b^=ans;
157 int rt1=find(root_fa[i-1],a),rt2=find(root_fa[i-1],b);
158 // printf("root[%d]=%d,root[%d]=%d\n",a,rt1,b,rt2);
159 if(rt1==rt2)
160 {
161 root_fa[i]=root_fa[i-1];
162 root_rankk[i]=root_rankk[i-1];
163 }
164 else
165 {
166 int rk1=search_rankk(root_rankk[i-1],rt1,1,n),rk2=search_rankk(root_rankk[i-1],rt2,1,n);
167 if(rk1<rk2)
168 {
169 insert_fa(root_fa[i-1],root_fa[i],rt1,rt2,1,n);
170 root_rankk[i]=root_rankk[i-1];
171 }
172 else
173 {
174 insert_fa(root_fa[i-1],root_fa[i],rt2,rt1,1,n);
175 if(rk1==rk2)
176 insert_rankk(root_rankk[i-1],root_rankk[i],rt1,1,n);
177 else
178 root_rankk[i]=root_rankk[i-1];
179 }
180 }
181 // printf("search_fa[2]=%d\n",search_fa(root_fa[1],2) );
182 // printf("root[%d]=%d,root[%d]=%d\n",a,find(root_fa[i],a),b,find(root_fa[i],b));
183 }
184 else if(q==2)
185 {
186 k=read();
187 // scanf("%d",&k);
188 k^=ans;
189 root_fa[i]=root_fa[k];
190 root_rankk[i]=root_rankk[k];
191 }
192 else if(q==3)
193 {
194 a=read();
195 b=read();
196 // scanf("%d%d",&a,&b);
197 root_fa[i]=root_fa[i-1];
198 root_rankk[i]=root_rankk[i-1];
199 a^=ans;
200 b^=ans;
201 if(find(root_fa[i],a)==find(root_fa[i],b))
202 ans=1;
203 else
204 ans=0;
205 printf("%d\n",ans);
206 }
207 //insert_fa(root_fa[i-1],root_fa[i],2,3);
208 // printf("root_fa[%d]:%d\n",i,root_fa[i]);
209 // printf("the %d watch:\n",i);
210 // watch(root_fa[i],1,n);
211 }
212 return 0;
213 }