Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const int N = 100 * 1000 + 10;
- const int H = 22;
- int go[N][H];
- int tin[N];
- int tout[N];
- int col[N];
- int size[N];
- vector<int> g[N];
- int timer;
- void dfs(int v, int c, int par) {
- if (g[v].size() == 0)
- size[v] = 1;
- go[v][0] = par;
- for (int h = 1; h < H; h++)
- go[v][h] = go[go[v][h - 1]][h - 1];
- tin[v] = timer++;
- col[v] = c;
- for (int to : g[v]) {
- dfs(to, c, v);
- size[v] += size[to];
- }
- tout[v] = timer++;
- }
- bool isAnc(int a, int b) {
- return tin[a] <= tin[b] && tin[b] <= tout[a];
- }
- int lca(int a, int b) {
- if (isAnc(a, b))
- return a;
- if (isAnc(b, a))
- return b;
- for (int h = H - 1; h >= 0; h--)
- if (!isAnc(go[a][h], b))
- a = go[a][h];
- return go[a][0];
- }
- typedef pair<int, int> pii;
- set<pii> at[N];
- int pipes[N];
- int people[N];
- int totPipes;
- int totPeople;
- void check(set<pii>& s, int& pipesAt, int& peopleAt) {
- if (s.size() == 0) {
- pipesAt = 0;
- peopleAt = 0;
- return;
- }
- auto it = s.begin();
- int fst = it->second;
- it = s.end();
- it--;
- int snd = it->second;
- int root = lca(fst, snd);
- pipesAt = 1;
- peopleAt = size[root] - s.size();
- }
- void add(int v, set<pii>& s, int& pipesAt, int& peopleAt) {
- totPipes -= pipesAt;
- totPeople -= peopleAt;
- s.insert(pii(tin[v], v));
- check(s, pipesAt, peopleAt);
- totPipes += pipesAt;
- totPeople += peopleAt;
- }
- void del(int v, set<pii>& s, int& pipesAt, int& peopleAt) {
- totPipes -= pipesAt;
- totPeople -= peopleAt;
- s.erase(pii(tin[v], v));
- check(s, pipesAt, peopleAt);
- totPipes += pipesAt;
- totPeople += peopleAt;
- }
- int main() {
- freopen("gangsters.in", "r", stdin);
- freopen("gangsters.out", "w", stdout);
- int n, q;
- scanf("%d%d", &n, &q);
- for (int i = 1; i < n; i++) {
- int p;
- scanf("%d", &p);
- p--;
- g[p].push_back(i);
- }
- for (int to : g[0])
- dfs(to, to, 0);
- for (int i = 0; i < q; i++) {
- char s[10];
- int v;
- scanf("%s%d", s, &v);
- if (s[0] == '+')
- add(v, at[col[v]], pipes[col[v]], people[col[v]]);
- else
- del(v, at[col[v]], pipes[col[v]], people[col[v]]);
- printf("%d %d\n", totPipes, totPeople);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement