Theme portal
First of all, you can understand the meaning of the problem once you look at the sample hand model.
Then I found out that it was another tree section.
Maintaining a segment tree, seg[rt].sum indicates the number of packages installed in that area
- Installation operation, jump to the root node, during which all the passing points are changed to installation.
- Uninstall operation, change all of your subtrees including your state to not install
It was found that the answer to both operations was delta(seg[1].sum).
Details need attention
Code:
#include <bits/stdc++.h> #define maxn 100010 #define ls rt << 1 #define rs rt << 1 | 1 using namespace std; struct Edge{ int to, next; }edge[maxn << 1]; struct Seg{ int l, r, sum, tag; }seg[maxn << 2]; int head[maxn], num, d[maxn], fa[maxn], size[maxn], son[maxn], id[maxn], cnt, top[maxn], n; inline int read(){ int s = 0, w = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') w = -1; for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48); return s * w; } void add_edge(int x, int y){ edge[++num].to = y; edge[num].next = head[x]; head[x] = num; } void dfs(int u){ size[u] = 1, son[u] = -1; for (int i = head[u]; i; i = edge[i].next){ int v = edge[i].to; if (v != fa[u]){ fa[v] = u, d[v] = d[u] + 1; dfs(v); size[u] += size[v]; if (son[u] == -1 || son[u] != -1 && size[son[u]] < size[v]) son[u] = v; } } } void dfs(int u, int x){ id[u] = ++cnt, top[u] = x; if (son[u] == -1) return; dfs(son[u], x); for (int i = head[u]; i; i = edge[i].next){ int v = edge[i].to; if (v != son[u] && v != fa[u]) dfs(v, v); } } void pushup(int rt){ seg[rt].sum = seg[ls].sum + seg[rs].sum; } void pushdown(int rt){Downward propagation tag seg[ls].sum = (seg[ls].r - seg[ls].l + 1) * seg[rt].tag; seg[rs].sum = (seg[rs].r - seg[rs].l + 1) * seg[rt].tag; seg[ls].tag = seg[rs].tag = seg[rt].tag; seg[rt].tag = -1; } void build(int rt, int l, int r){ seg[rt].l = l, seg[rt].r = r; seg[rt].tag = -1; if (l == r) return; int mid = (l + r) >> 1; build(ls, l, mid); build(rs, mid + 1, r); } void update(int rt, int l, int r, int k){ if (seg[rt].l > r || seg[rt].r < l) return; if (seg[rt].l >= l && seg[rt].r <= r){ seg[rt].sum = (seg[rt].r - seg[rt].l + 1) * k;//Change state seg[rt].tag = k; return; } if (seg[rt].tag != -1) pushdown(rt); update(ls, l, r, k); update(rs, l, r, k); pushup(rt); } int main(){ n = read(); for (int i = 1; i < n; ++i){ int x = read(); add_edge(x + 1, i + 1); add_edge(i + 1, x + 1); } dfs(1); dfs(1, 1); build(1, 1, n); int m = read(); while (m--){ char c = getchar(); for (; c != 'i' && c != 'u'; c = getchar()); if (c == 'i'){ int tmp = seg[1].sum, x = read(); ++x; while (top[x] != 1){ update(1, id[top[x]], id[x], 1); x = fa[top[x]]; } update(1, id[top[x]], id[x], 1); printf("%d\n", abs(tmp - seg[1].sum)); } else{ int tmp = seg[1].sum, x = read(); ++x; update(1, id[x], id[x] + size[x] - 1, 0); printf("%d\n", abs(tmp - seg[1].sum)); } } return 0; }