CodeForces 570D DFS序 树状数组 Tree Requests
参考九野巨巨的博客。
查询一个子树内的信息,可以通过DFS序转成线形的,从而用数据结构来维护。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <map> 6 #define MP make_pair 7 #define FI first 8 #define SE second 9 using namespace std; 10 11 typedef pair<int, int> PII; 12 13 const int maxn = 500000 + 10; 14 15 int n, m; 16 17 vector<int> G[maxn]; 18 char s[maxn]; 19 20 struct BIT 21 { 22 int C[maxn]; 23 24 inline int lowbit(int x) { return x & (-x); } 25 26 void add(int x, int v) 27 { 28 while(x <= n) C[x] += v, x += lowbit(x); 29 } 30 31 int sum(int x) 32 { 33 int ans = 0; 34 while(x) ans += C[x], x -= lowbit(x); 35 return ans; 36 } 37 38 int Query(int l, int r) { return sum(r) - sum(l - 1); } 39 40 }T[26]; 41 42 vector<int> Dep[maxn]; 43 int dfs_clock; 44 int pre[maxn], post[maxn]; 45 46 void dfs(int u, int dep) 47 { 48 Dep[dep].push_back(u); 49 pre[u] = ++dfs_clock; 50 for(int v : G[u]) dfs(v, dep + 1); 51 post[u] = dfs_clock; 52 } 53 54 vector<PII> queries[maxn]; 55 56 bool ans[maxn]; 57 58 int main() 59 { 60 scanf("%d%d", &n, &m); 61 for(int i = 2; i <= n; i++) 62 { 63 int u; scanf("%d", &u); 64 G[u].push_back(i); 65 } 66 scanf("%s", s + 1); 67 68 int maxh = 1; 69 for(int i = 0; i < m; i++) 70 { 71 int v, h; scanf("%d%d", &v, &h); 72 maxh = max(maxh, h); 73 queries[h].push_back(MP(v, i)); 74 } 75 76 dfs(1, 1); 77 78 for(int i = 0; i < m; i++) ans[i] = true; 79 80 for(int i = 1; i <= maxh; i++) 81 { 82 if(Dep[i].empty()) break; 83 if(queries[i].empty()) continue; 84 85 for(int v : Dep[i]) T[s[v] - 'a'].add(pre[v], 1); 86 87 for(PII x : queries[i]) 88 { 89 int odd = 0; 90 for(int j = 0; j < 26; j++) 91 { 92 odd += (T[j].Query(pre[x.FI], post[x.FI]) & 1); 93 } 94 if(odd >= 2) ans[x.SE] = false; 95 } 96 97 for(int v : Dep[i]) T[s[v] - 'a'].add(pre[v], -1); 98 } 99 100 for(int i = 0; i < m; i++) printf("%s\n", ans[i] ? "Yes" : "No"); 101 102 return 0; 103 }