1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| int rt[N], rTop; vector<PII> q[N];
int fa[N], dep[N], siz[N], hs[N], top[N], dfn[N], stamp; int node[N];
int cnt[N], ans[N];
inline void add(int u) { cnt[dep[u]] ++; } inline void del(int u) { cnt[dep[u]] --; }
void dfs1(int u, int depth) { dep[u] = depth, siz[u] = 1; for (int i = head[u], j; ~i; i = edge[i].nxt) { j = edge[i].to; dfs1(j, depth + 1); siz[u] += siz[j]; if (siz[j] > siz[hs[u]]) hs[u] = j; } return; }
void dfs2(int u, int Top) { dfn[u] = ++ stamp, top[u] = Top, node[stamp] = u; if (!hs[u]) return; dfs2(hs[u], Top); for (int i = head[u], j; ~i; i = edge[i].nxt) { j = edge[i].to; if (!top[j]) dfs2(j, j); } return; }
void dfs3(int u, bool kp) { for (int i = head[u]; ~i; i = edge[i].nxt) if (edge[i].to != hs[u]) dfs3(edge[i].to, false); if (hs[u]) dfs3(hs[u], true); for (int i = head[u], j; ~i; i = edge[i].nxt) { j = edge[i].to; if (j == hs[u]) continue; for (int k = dfn[j]; k <= dfn[j] + siz[j] - 1; ++ k) add(node[k]); } add(u); for (auto t : q[u]) ans[t.second] = cnt[t.first + dep[u]]; if (!kp) for (int i = dfn[u]; i <= dfn[u] + siz[u] - 1; ++ i) del(node[i]); return; }
int query(int u, int kth) { while (kth >= dfn[u] - dfn[top[u]] + 1 and u) { kth -= dfn[u] - dfn[top[u]] + 1; u = fa[top[u]]; } return node[dfn[u] - kth]; }
int main() { memset(head, -1, sizeof head); input(n); for (int i = 1; i <= n; ++ i) { input(fa[i]); if (fa[i]) add(fa[i], i); else rt[++ rTop] = i; } for (int i = 1; i <= rTop; ++ i) dfs1(rt[i], 1), dfs2(rt[i], rt[i]); input(m); for (int i = 1, x, y, z; i <= m; ++ i) { input(x), input(y); z = query(x, y); q[z].push_back({y, i}); } for (int i = 1; i <= rTop; ++ i) dfs3(rt[i], 0); for (int i = 1; i <= m; ++ i) output(max(ans[i] - 1, 0), " \n"[i == m]); return 0; }
|