1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <iostream> #define mid (l + r) >> 1 using namespace std; const int maxn = 200010; int n, m, cnt_tree = 0,cur; int root[maxn], fa[maxn << 5], ranks[maxn << 5];
struct node { int l, r; } tree[maxn << 5];
inline int read( ){ register int x = 0, t = 1; register char c = getchar(); while(c < '0' || c > '9') {if(c=='-')t=-1;c=getchar();} while(c >= '0' && c <= '9') {x=(x<<1)+(x<<3)+(c-48);c=getchar();} return x*t; }
int build(int l, int r) { int rt = ++cnt_tree; if (l == r) { fa[rt] = l; ranks[rt] = 1; return rt; } int m = mid; tree[rt].l = build(l, m); tree[rt].r = build(m + 1, r); return rt; }
int update(int pre, int x, int val, int l, int r) { int rt = ++cnt_tree; tree[rt] = tree[pre]; ranks[rt] = ranks[pre]; fa[rt] = fa[pre]; if (l == r ) { fa[rt] = val; return rt; } int m = mid; if (x <= m) tree[rt].l = update(tree[pre].l, x, val, l, m); else tree[rt].r = update(tree[pre].r, x, val, m + 1, r); return rt; }
int update_depth(int pre, int x, int l,int r){ int now = 0; if (pre == root[cur]) now = pre; else now = ++cnt_tree; tree[now] = tree[pre]; ranks[now] = ranks[pre]; fa[now] = fa[pre]; if (l == r) { ranks[now]++; return now; } else{ int m = mid; if (x <= m) tree[now].l = update_depth(tree[pre].l, x,l,m); else tree[now].r = update_depth(tree[pre].r, x,m+1,r); } return now; }
int query(int x, int rt, int l, int r) { if (l == r ) return rt; int m = mid; return (x <= m) ? query(x, tree[rt].l, l, m) : query(x, tree[rt].r, m + 1, r); }
int find(int k) { int get_fa = query(k, root[cur], 1, n); return (k == fa[get_fa]) ? get_fa : find(fa[get_fa]); }
void Union(int x, int y) { if (ranks[x] < ranks[y]) swap(x, y); root[cur] = update(root[cur], fa[y], fa[x], 1,n); if (ranks[x] == ranks[y]) update_depth(root[cur], fa[x], 1,n); }
int main() { n = read(); m = read(); root[0] = build(1, n); int opt, x, y; for (int i = 1; i <= m; i++) { opt = read(); root[i] = root[i - 1]; cur = i; if (opt == 1) { x = read(); y = read(); x = find(x); y = find(y); if (fa[x] != fa[y]) Union(x, y); } else if (opt == 2) { x = read(); root[i] = root[x]; } else { x = read(); y = read(); x = find(x); y = find(y); if (x == y) puts("1"); else puts("0"); } } return 0; }
|