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 }