WA on #9,思路大概是用一个 multimap 维护目前的名字,hash_table 是用来把名字转化为权值的。
#include <bits/stdc++.h>
#include <bits/extc++.h>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
const int N = 2e5 + 5;
int n, q, fr, rt[N], sz[N], dep[N], hsn[N], vis[N], cnt, a[N], heavy, ans[N];
multiset <int> s;
gp_hash_table <string, int> hs;
struct Qr{
int Dep, id;
};
vector <int> G[N];
vector <Qr> qr[N];
void dfs1(int u, int ff) {
sz[u] = 1;
for (int v : G[u]) {
if(v == ff) continue;
dep[v] = dep[u] + 1;
dfs1(v, u);
sz[u] += sz[v];
if(sz[v] > sz[hsn[u]]) hsn[u] = v;
}
return ;
}
void update(int u, int ff, int val) {
if(val == 1) {
if(s.find(a[u]) == s.end()) vis[dep[u]]++;
s.insert(a[u]);
}
else {
s.erase(s.find(a[u]));
if(s.find(a[u]) == s.end()) vis[dep[u]]--;
}
for (int v : G[u]) {
if(v == ff || v == heavy) continue;
update(v, u, val);
}
return ;
}
void dfs2(int u, int ff, int ish) {
for (int v : G[u]) {
if(v == ff || v == hsn[u]) continue;
dfs2(v, u, 0);
}
if(hsn[u]) dfs2(hsn[u], u, 1), heavy = hsn[u];
update(u, ff, 1);
for (int i = 0; i < qr[u].size(); ++i) ans[qr[u][i].id] = vis[qr[u][i].Dep];
heavy = 0;
if(!ish) update(u, ff, -1);
return ;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
string s; int r; cin >> s; scanf("%d", &r);
if(!hs[s]) hs[s] = ++cnt;
a[i] = hs[s];
if(r == 0) rt[++fr] = i;
else G[r].emplace_back(i);
}
for (int i = 1; i <= fr; ++i) dfs1(rt[i], 0);
scanf("%d", &q);
for (int i = 1; i <= q; ++i) {
int x, y; scanf("%d%d", &x, &y);
qr[x].emplace_back((Qr){dep[x] + y, i});
}
for (int i = 1; i <= fr; ++i) dfs2(rt[i], 0, 0);
for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
return 0;
}