Codeforces 570D Tree Requests(树上启发式合并)

题目链接 Tree Requests

 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 typedef long long LL;
 8 
 9 const int N = 500010;
10 const int A = 31;
11 
12 int cntf[N], sz[N], h[N];
13 vector <int> v[N];
14 vector <pair<int, int> > query[N];
15 
16 char s[N];
17 bool skip[N], cnt[N][A], ans[N];
18 int n, m, x, y;
19 
20 void getsz(int x, int dep){
21         sz[x] = 1; h[x] = dep;
22         for (auto u : v[x]){
23             getsz(u, dep + 1);
24             sz[x] += sz[u];
25         }
26 }
27 
28 void add(int x, int val){
29     cntf[h[x]] -= cnt[h[x]][s[x] - 'a'];
30     cnt[h[x]][s[x] - 'a'] ^= 1;
31     cntf[h[x]] += cnt[h[x]][s[x] - 'a'];
32         
33     for (auto u : v[x]) if (!skip[u]) add(u, val);
34 }
35     
36 
37 void dfs(int x, bool keep){
38         int mx = 0, p;
39         for (auto u : v[x]){
40                 if (sz[u] > mx){
41                         mx = sz[u];
42                         p = u;
43                 }
44         }
45         
46         for (auto u : v[x]) if (u != p) dfs(u, 0);
47         if (mx) skip[p] = 1, dfs(p, 1);
48         
49         add(x, 1);
50         for (auto q : query[x]){
51                 ans[q.second] = cntf[q.first] <= 1;
52         }
53         
54         if (mx) skip[p] = 0;
55         if (!keep) add(x, -1);
56 }               
57 
58 int main(){
59     
60     scanf("%d%d", &n, &m);
61     rep(i, 2, n){
62         scanf("%d", &x);
63         v[x].push_back(i);
64     }
65     
66     scanf("%s", s + 1);
67     
68     getsz(1, 1);
69     
70     rep(i, 1, m){
71         scanf("%d%d", &x, &y);
72         query[x].push_back({y, i});
73     }
74     
75     memset(ans, 0, sizeof ans);
76     dfs(1, 0);
77     rep(i, 1, m) puts(ans[i] ? "Yes" : "No");
78 
79     return 0;
80 }

 

posted @ 2017-05-02 22:23  cxhscst2  阅读(453)  评论(0编辑  收藏  举报