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 }

 

转载于:https://www.cnblogs.com/cxhscst2/p/6798686.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值