G.gangsters in Central city
Test instructions: A tree, Node 1 is the root, is the water source. Water flows along the edge to the leaves. There is a house on each leaf of the tree. There are Q queries, one for the house U was invaded by bandits, and the other for robbers to evacuate the house U. For each inquiry, the minimum number of valves is required to block the flow of water to the robber's house, and the minimum number of valves in the case of the smallest accidental house count (i.e., the house without being invaded but water-cut).
Thought: Observation can be found, and the root of the sub-tree is independent, so there is every one of these sub-tree has bandits, then ans1++, each one of these sub-tree bandits all evacuated ans1--; So to maintain is the number of injuries ans2, we have to each of the root of the tree connected to the independent processing. To minimize the ANS2, the valve must be set in the House of the robber in the upper part of the LCA, the current injury number for the LCA as the root of the sub-leaf number of nodes minus the number of bandits, and then minus the original number of injuries, you can use the Difference value update ans2. For the LCA of all robbers in a subtree, it is necessary to know one conclusion: the LCA of several nodes is the LCA of two nodes with the largest and smallest DFS sequence. Therefore, several sets can be opened to maintain the DFS sequence of the bandit nodes within each subtree.
#include <algorithm> #include <cstdio> #include <iostream> #include <cstring> #include < vector> #include <set> #define DD (x) cout<< #x << "=" <<x<< "" #define DE (x) cout<<# x<< "=" <<x<<endl#define pb Push_back#define All (x) X.begin (), X.end () using namespace Std;const int Maxn=1e5+10;int head[maxn],cnt=0;struct edge{int v,ne;} edge[maxn<<1];void Add (int u,int v) {edge[++cnt].ne=h Ead[u]; Edge[cnt].v=v; head[u]=cnt;} int Tot=0,fa[maxn][32],dep[maxn],sz[maxn],id[maxn],rk[maxn];//sz records the number of leaf nodes vector<int> tree;void dfs (int f,int u, int deep) {Id[u]=++tot; Rk[tot]=u; Dep[u]=deep; sz[u]=edge[head[u]].ne==0; Fa[u][0]=f; if (f==1) TREE.PB (Id[u]); for (int i=1; i<=22; ++i) fa[u][i]=fa[fa[u][i-1]][i-1]; for (int i=head[u]; i; i=edge[i].ne) {int v=edge[i].v; if (v==f) continue; DFS (U,V,DEEP+1); SZ[U]+=SZ[V]; }}int LCA (int u,intV) {if (Dep[u]<dep[v]) swap (U,V); for (int i=22,d=dep[u]-dep[v]; i>=0;-I. If (d& (1<<i)) u=fa[u][i]; if (u==v) return u; for (int i=22; i>=0;-I.) if (Fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i]; return fa[u][0];} Set<int> St[maxn];int Gan[maxn],man[maxn];//gan is the bandit number, man is the wounded number int main () {freopen ("gangsters.in", "R", stdin); Freopen ("Gangsters.out", "w", stdout); int n,q; scanf ("%d%d", &n,&q); for (int i=2; i<=n; ++i) {int V; scanf ("%d", &v); Add (I,V); Add (v,i); } dfs (1,1,1); int ans1=0,ans2=0; while (q--) {char op[2]; int u; scanf ("%s%d", op,&u); int Num=upper_bound (All (tree), Id[u])-tree.begin ();//You are judged by the DFS sequence of u within which subtree if (op[0]== ' + ') {st[num].i Nsert (Id[u]); int Mn=*st[num].begin (), mx=* (--st[num].end ()), A=lca (Rk[mx],rk[mn]); if (!gan[num]) ans1++; gan[num]++; Ans2+=sz[a]-gan[num]-man[num]; Man[num]=sz[a]-gan[num]; } else {st[num].erase (Lower_bound (All (St[num]), id[u])); gan[num]--; if (!gan[num]) {ans1--; Ans2-=man[num]; man[num]=0; } else {int mn=*st[num].begin (), mx=* (--st[num].end ()), A=lca (Rk[mx],rk[mn]); Ans2+=sz[a]-gan[num]-man[num]; Man[num]=sz[a]-gan[num]; }} printf ("%d%d\n", ans1,ans2); } return 0;}
Neerc, Northern subregional Contest g.gangsters in Central city (LCA)