自从zkysb出了可持久化并查集后……
hzwer:乱写能AC,暴力踩标程
KuribohG:我不路径压缩就过了!
ndsf:暴力就可以轻松虐!
zky:……
n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
请注意本题采用强制在线,所给的a,b,k均经过加密,加密方法为x = x xor lastans,lastans的初始值为0
0<n,m<=2*10^5
1 //It is made by Awson on 2017.10.5
2 #include <map>
3 #include <set>
4 #include <cmath>
5 #include <ctime>
6 #include <queue>
7 #include <stack>
8 #include <vector>
9 #include <cstdio>
10 #include <string>
11 #include <cstdlib>
12 #include <cstring>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Max(a, b) ((a) > (b) ? (a) : (b))
17 #define Min(a, b) ((a) < (b) ? (a) : (b))
18 #define sqr(x) ((x)*(x))
19 using namespace std;
20 const int N = 2e5;
21 void read(int &x) {
22 char ch; bool flag = 0;
23 for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == ‘-‘)) || 1); ch = getchar());
24 for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
25 x *= 1-2*flag;
26 }
27
28 struct node {
29 int key;
30 node *child[2];
31 }sgm[N*30+5], *pos = sgm;
32 node* root[N+5];
33 int dep[N+5];
34 int n, m, lastans;
35 int opt, a, b;
36
37 void build(node* &o, int l, int r) {
38 if (l == r) {
39 dep[l] = 1;
40 return;
41 }
42 int mid = (l+r)>>1;
43 o->child[0] = ++pos, build(o->child[0], l, mid);
44 o->child[1] = ++pos, build(o->child[1], mid+1, r);
45 }
46 void update(node* &o, int l, int r, int loc, int val) {
47 node* t = o;
48 o = ++pos;
49 if (l == r) {
50 o->key = val;
51 return;
52 } else {
53 o->child[0] = t->child[0];
54 o->child[1] = t->child[1];
55 }
56 int mid = (l+r)>>1;
57 if (loc <= mid) update(o->child[0], l, mid, loc, val);
58 else update(o->child[1], mid+1, r, loc, val);
59 }
60 int query(node *o, int l, int r, int loc) {
61 if (l == r) return o->key;
62 int mid = (l+r)>>1;
63 if (loc <= mid) return query(o->child[0], l, mid, loc);
64 else return query(o->child[1], mid+1, r, loc);
65 }
66 int find(node *o, int loc) {
67 while (true) {
68 int tmp = query(o, 1, n, loc);
69 if (!tmp) return loc;
70 loc = tmp;
71 }
72 }
73 void work() {
74 read(n), read(m);
75 root[0] = pos;
76 build(root[0], 1, n);
77 for (int i = 1; i <= m; i++) {
78 read(opt);
79 if (opt == 1) {
80 root[i] = root[i-1];
81 read(a), read(b);
82 a ^= lastans, b ^= lastans;
83 int p = find(root[i], a);
84 int q = find(root[i], b);
85 if (p != q) {
86 if (dep[p] == dep[q]) dep[p]++;
87 else if (dep[p] < dep[q]) swap(p, q);
88 update(root[i], 1, n, q, p);
89 }
90 }
91 else if (opt == 2) read(a), a ^= lastans, root[i] = root[a];
92 else {
93 read(a), read(b);
94 a ^= lastans, b ^= lastans;
95 root[i] = root[i-1];
96 int p = find(root[i], a);
97 int q = find(root[i], b);
98 if (p != q) printf("0\n"), lastans = 0;
99 else printf("1\n"), lastans = 1;
100 }
101 }
102 }
103 int main() {
104 work();
105 return 0;
106 }