我第一次过这个题的代码是这样的:
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define rep(i, s, e) for (re int i = s; i <= e; ++i)
#define drep(i, s, e) for (re int i = s; i >= e; --i)
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)
const int N = 200000 + 10;
const int MLOG = 40;
il int read() {
int x = 0; bool f = true; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = false; c = getchar();}
while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? x : -x;
}
int n, m, dep[N];
int tot, val[N * MLOG], lson[N * MLOG], rson[N * MLOG], rt[N];
#define ls lson[u]
#define rs rson[u]
#define mid ((l + r) >> 1)
int build(int l, int r) {
int u = ++tot;
if (l == r) { val[u] = l; return u; }
ls = build(l, mid), rs = build(mid + 1, r);
return u;
}
il int clone(int u) {
val[++tot] = val[u], lson[tot] = ls, rson[tot] = rs;
return tot;
}
int modify(int p, int x, int now, int l, int r) {
int u = clone(now);
if (l == r) { val[u] = x; return u; }
if (p <= mid) ls = modify(p, x, ls, l, mid);
else rs = modify(p, x, rs, mid + 1, r);
return u;
}
int query(int p, int u, int l, int r) {
if (l == r) return val[u];
return (p <= mid) ? query(p, ls, l, mid) : query(p, rs, mid + 1, r);
}
int getf(int u, int ver) {
for (int nxt = query(u, rt[ver], 1, n); u != nxt; u = nxt, nxt = query(u, rt[ver], 1, n)) ;
return u;
}
int main() {
n = read(), m = read(), rt[0] = build(1, n);
rep(i, 1, n) dep[i] = 1;
rep(i, 1, m) {
int opt = read();
if (opt == 1) {
int u = getf(read(), i - 1), v = getf(read(), i - 1);
if (dep[u] > dep[v]) swap(u, v);
else if (dep[u] == dep[v]) ++dep[v];
rt[i] = modify(u, v, rt[i - 1], 1, n);
}
else if (opt == 2) rt[i] = rt[read()];
else {
rt[i] = rt[i - 1];
int u = getf(read(), i), v = getf(read(), i);
printf("%d\n", u == v);
}
}
return 0;
}
大家可以很明显地看到我代码中的 dep
没有用可持久化数组维护,相当于直接从上一次操作继承,这样显然是错的(可以先把一个点的 dep
弄到很大,再把小的弄成一条链挂在它下面然后多次查询卡掉它),但是它过了。。。
所以管理能否加强一下数据呢