Codeforces 246E Blood Cousins Return(树上启发式合并)

题目链接 Blood Cousins Return

 

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define rep(i, a, b) for (int i(a); i <= (b); ++i)
 6 
 7 const int N = 200010;
 8 
 9 string s[N];
10 int ans[N], sz[N], h[N];
11 bool skip[N];
12 vector <int> v[N];
13 vector < pair<int, int> > query[N];
14 int n, m, x, y, q;
15 
16 unordered_map <string, int> mp[N];
17     
18 void getsz(int x){
19     sz[x] = 1;
20     for (auto u : v[x])
21         h[u] = h[x] + 1, getsz(u), sz[x] += sz[u];
22 }
23 
24 void del(int x){
25     auto it = mp[h[x]].find(s[x]);
26     --it->second;
27     if (!it->second) mp[h[x]].erase(it);
28     for (auto u : v[x]) if (!skip[u]) del(u);
29 }
30 
31 void add(int x){
32     mp[h[x]][s[x]]++;
33     for (auto u : v[x]) if (!skip[u]) add(u);
34 }
35 
36 void dfs(int x, bool keep = 0){
37     int mx = 0, p = 0;
38     for (auto u : v[x]) if (mx < sz[u]){ mx = sz[u]; p = u;}
39     for (auto u : v[x]) if (u != p) dfs(u, 1);
40     if (p) dfs(p), skip[p] = 1;
41     
42     add(x);
43     for (auto q: query[x])
44         ans[q.second] = mp[h[x] + q.first].size();
45     
46     if (p) skip[p] = 0;
47     if (keep) del(x);
48 }
49         
50 
51 int main(){
52     
53     scanf("%d", &n);
54     rep(i, 1, n){
55         cin >> s[i] >> x;
56         v[x].push_back(i);
57     }
58     
59     scanf("%d", &q);
60     rep(i, 1, q){
61         scanf("%d%d", &x, &y);
62         query[x].push_back({y, i});
63     }
64     
65     getsz(0);
66     dfs(0);
67     
68     rep(i, 1, q) printf("%d\n", ans[i]);
69     return 0;
70 }

 

posted @ 2017-05-02 21:52  cxhscst2  阅读(447)  评论(0编辑  收藏  举报