https://www.luogu.org/problemnew/show/P2146
几乎是一个裸题
#include<cstdio> #include<cstring> #include<algorithm> #define ls (p << 1) #define rs ((p << 1) | 1) #define mid ((l + r) >> 1) const int N = 200010, M = N << 2; using namespace std; int n, Q, last[N], pre[N], now[N], son[N], tot, a[N], cnt, w[N], size[N]; int hson[N], top[N], fa[N], dep[N]; char op[12]; struct Tree { int sum[M], cov[M], size[M]; void down(int p) { if (cov[p] != -1) { sum[ls] = size[ls] * cov[p], sum[rs] = size[rs] * cov[p]; cov[ls] = cov[rs] = cov[p], cov[p] = -1; } } void build(int p, int l, int r) { if (l == r) { sum[p] = 0, cov[p] = -1, size[p] = 1; return; } build(ls, l, mid), build(rs, mid + 1, r); sum[p] = sum[ls] + sum[rs], size[p] = size[ls] + size[rs]; } void change(int p, int l, int r, int a, int b, int v) { if (l == a && r == b) { sum[p] = v * size[p], cov[p] = v; return; } down(p); if (b <= mid) change(ls, l, mid, a, b, v); else if (a > mid) change(rs, mid + 1, r, a, b, v); else change(ls, l, mid, a, mid, v), change(rs, mid + 1, r, mid + 1, b, v); sum[p] = sum[ls] + sum[rs]; } int query(int p, int l, int r, int a, int b) { if (l == a && r == b) { return sum[p]; } down(p); if (b <= mid) return query(ls, l, mid, a, b); else if (a > mid) return query(rs, mid + 1, r, a, b); else return query(ls, l, mid, a, mid) + query(rs, mid + 1, r, mid + 1, b); } } Seg; void add(int a, int b) { pre[++ tot] = now[a], now[a] = tot, son[tot] = b; } void dfs(int x) { size[x] = 1; for (int y = now[x]; y; y = pre[y]) if (son[y] != fa[x]) { fa[son[y]] = x, dep[son[y]] = dep[x] + 1; dfs(son[y]), size[x] += size[son[y]]; if (size[son[y]] > size[hson[x]]) hson[x] = son[y]; } } void btree(int x, int tp) { w[x] = ++ cnt, a[cnt] = 0, top[x] = tp; if (hson[x]) btree(hson[x], tp); for (int y = now[x]; y; y = pre[y]) if (son[y] != fa[x] && son[y] != hson[x]) btree(son[y], son[y]); last[x] = cnt; } void answer(int a,int b) { int f1 = top[a], f2 = top[b], sum = 0, num = dep[b] - dep[a] + 1; while (f1 != f2) { if (dep[f1] < dep[f2]) swap(f1, f2), swap(a, b); sum += Seg.query(1, 1, n, w[f1], w[a]); Seg.change(1, 1, n, w[f1], w[a], 1); a = fa[f1], f1 = top[a]; } if (dep[a] > dep[b]) swap(a, b); sum += Seg.query(1, 1, n, w[a], w[b]); Seg.change(1, 1, n, w[a], w[b], 1); printf("%d\n", num - sum); } int main() { scanf("%d", &n); for (int i = 2, x; i <= n; i ++) scanf("%d", &x), x ++, add(x, i); dfs(1), btree(1, 1), Seg.build(1, 1, n); scanf("%d", &Q); for (int i = 1, x; i <= Q; i ++) { scanf("%s%d", op, &x), x ++; if (op[0] == ‘i‘) answer(1, x); else { printf("%d\n", Seg.query(1, 1, n, w[x], last[x])); Seg.change(1, 1, n, w[x], last[x], 0); } } return 0; }