【题目链接】
【双倍经验链接】
【思路要点】
- 用可持久化线段树实现可持久化数组。
- 时间复杂度 O(NLog2N) O ( N L o g 2 N ) 。
【代码】
#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define MAXP 10000005
template <typename T> void read(T &x) {
x = 0; int f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
struct Persisent_Segment_Tree {
struct Node {
int lc, rc;
//Non-leaf : lc -> leftchild, rc -> rightchild
//Leaf : lc -> father, rc -> size
} a[MAXP];
int root[MAXN];
int n, size, version;
void build(int &root, int l, int r) {
if (root == 0) root = ++size;
if (l == r) {
a[root].lc = l;
a[root].rc = 1;
return;
}
int mid = (l + r) / 2;
build(a[root].lc, l, mid);
build(a[root].rc, mid + 1, r);
}
void init(int x) {
n = x;
size = 0;
version = 0;
build(root[0], 1, n);
}
void restore(int old) {
root[++version] = root[old];
}
pair <int, int> query(int root, int l, int r, int pos) {
if (l == r) return make_pair(a[root].lc, a[root].rc);
int mid = (l + r) / 2;
if (mid >= pos) return query(a[root].lc, l, mid, pos);
else return query(a[root].rc, mid + 1, r, pos);
}
pair <int, int> getroot(int x) {
pair <int, int> tmp = query(root[version], 1, n, x);
if (tmp.first == x) return tmp;
else return getroot(tmp.first);
}
int modify(int root, int l, int r, int pos, int vl, int vr) {
if (l == r) {
size++;
a[size].lc = vl;
a[size].rc = vr;
return size;
}
int mid = (l + r) / 2;
int ans = ++size;
a[ans] = a[root];
if (mid >= pos) a[ans].lc = modify(a[root].lc, l, mid, pos, vl, vr);
else a[ans].rc = modify(a[root].rc, mid + 1, r, pos, vl, vr);
return ans;
}
void merge(int x, int y) {
pair <int, int> rx = getroot(x);
pair <int, int> ry = getroot(y);
if (rx.second < ry.second) {
version++;
root[version] = root[version - 1];
root[version] = modify(root[version], 1, n, rx.first, ry.first, rx.second);
root[version] = modify(root[version], 1, n, ry.first, ry.first, rx.second + ry.second);
} else {
version++;
root[version] = root[version - 1];
root[version] = modify(root[version], 1, n, ry.first, rx.first, ry.second);
root[version] = modify(root[version], 1, n, rx.first, rx.first, rx.second + ry.second);
}
}
int query(int x, int y) {
version++;
root[version] = root[version - 1];
pair <int, int> rx = getroot(x);
pair <int, int> ry = getroot(y);
return rx.first == ry.first;
}
} PST;
int main() {
int n, m;
read(n), read(m);
PST.init(n);
for (int i = 1; i <= m; i++) {
int opt, x, y;
read(opt);
if (opt == 1) {
read(x), read(y);
PST.merge(x, y);
}
if (opt == 2) {
read(x);
PST.restore(x);
}
if (opt == 3) {
read(x), read(y);
printf("%d\n", PST.query(x, y));
}
}
return 0;
}