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 }
代码君

 

posted @ 2015-08-15 10:40  AOQNRMGYXLMV  阅读(227)  评论(0编辑  收藏  举报