Test instructions
Given \ (n\) packages, each package has a dependent package, the installation of a package must install his dependent package, uninstalling a package must first uninstall all dependent on its package. Given \ (m\) This operation, each time an operation \ (install/unistall\) represents the installation or uninstallation.
Exercises
It can be seen from a simple drawing that, on the hierarchical graph of the tree structure, installing a package is equivalent to installing all the packages on the path to the root node, deleting a package that is equivalent to deleting its sub-tree. Use a heavy-chain split + line tree to work on it.
#include <cstdio> #include <algorithm>using std::swap;typedef long long ll;const int n = 1e5 + 10;int N, Q, X, Ans;int Fa[n], dep[n], siz[n], Son[n];int top[n], dfn[n], Time;int cnt, from[n], to[n], Nxt[n];int bui[n << 2], set[ N << 2];inline void Addedge (int u, int v) {to[++cnt] = V, nxt[cnt] = From[u], from[u] = cnt;} void dfs1 (int u) {Siz[u] = 1, dep[u] = Dep[fa[u]] + 1; for (int i = from[u]; i; i = nxt[i]) {int v = to[i]; DFS1 (v), siz[u] + = Siz[v]; if (Siz[v] > Siz[son[u]]) son[u] = v; }}void DFS2 (int u, int t) {Dfn[u] = ++time, top[u] = t; if (!son[u]) return; DFS2 (Son[u], T); for (int i = from[u]; i; i = nxt[i]) {int v = to[i]; if (v = = Son[u]) continue; DFS2 (V, v); }}void Modify (int sl, int sr, int k, int o = 1, int l = 1, int r = n) {int len = r-l + 1; if (l >= SL && R <= Sr) {if (k = = 1) ans + = Len-bui[o], bui[o] = len; else ans + = Bui[o], bui[o] = 0; set[O] = k; return; } int mid = (L + r) >> 1, LC = O << 1, rc = LC | 1; if (Set[o]) {if (set[o] = = 1) BUI[LC] = (Len-(Len >> 1)), BUI[RC] = (len >> 1); else BUI[LC] = BUI[RC] = 0; SET[LC] = SET[RC] = Set[o], set[o] = 0; } if (SL <= mid) Modify (SL, SR, K, LC, L, mid); if (SR > Mid) Modify (SL, SR, K, RC, Mid + 1, R); Bui[o] = BUI[LC] + BUI[RC];} inline void ins (int x) {int FX = top[x]; while (FX! = 1) Modify (Dfn[fx], dfn[x], 1), x = Fa[fx], FX = top[x]; Modify (1, dfn[x], 1);} int main () {scanf ("%d", &n); for (int i = 2; I <= n; ++i) {scanf ("%d", fa + i), ++fa[i]; Addedge (Fa[i], i); } DFS1 (1), DFS2 (1, 1); scanf ("%d", &q); Char opt[12]; while (q--) {scanf ("\n%s%d", opt, &x), ans = 0, ++x; if (opt[0] = = ' I ') ins (x); else modify (Dfn[x], dfn[x] + siz[x]-1,-1); printf ("%d\n", ans); } return 0;}
Luogu P2146 Package Manager (tree chain split + line segment tree)