codeforces 570 D. Tree Requests (dfs)

题目链接:

  570 D. Tree Requests

题目描述:

  给出一棵树,有n个节点,1号节点为根节点深度为1。每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变成一个回文串?

解题思路:

  判断是不是回文串,可以统计集合中出现过的字母的个数,出现奇数次的字母个数小于1,即为回文串,否则不是。所以我们可以使用状压统计当前区间中字母出现的奇偶次数。

  对于如何快速的求出区间,先dfs整棵树,标记下来每个节点进栈的时间和出栈的时间,然后把高度一样的点按照进栈时间顺序升序存在一起。如果节点x的时间戳为(s, e),那么以x为根节点的子树中所有的节点的时间戳都在这个区间内,不在这个子树中的节点的时间戳都不在这个区间内。辣么我们就可以二分高度为h的节点寻找时间戳在(s,e)区间内的节点咯。

  思路是这样的,但是就是一直Runtime error on test 15,有没有很神奇。然后就去tokers的博客膜拜一下,最后代码几乎改成一样的了,但是Runtime error on test 15一直执着的不愿离我而去。一怒之下,全部删光光,重写一边就AC了(┭┮﹏┭┮重写大法好..........)

 

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 500100;
  4 
  5 int L[maxn], R[maxn], rp[maxn];
  6 int dfn, dep[maxn];
  7 char str[maxn];
  8 vector < int > sum[maxn];
  9 vector < int > node[maxn];
 10 vector < int > tree[maxn];
 11 
 12 void dfs (int u)
 13 {
 14     L[u] = ++dfn;
 15     rp[L[u]] = u;
 16     node[dep[u]].push_back(L[u]);
 17     for (int i=0; i<tree[u].size(); i++)
 18     {
 19         int v = tree[u][i];
 20         dep[v] = dep[u] + 1;
 21         dfs (v);
 22     }
 23     R[u] = dfn;
 24 }
 25 
 26 void init (int n)
 27 {
 28     dfn = 0;
 29     dep[1] = 1;
 30     for (int i=1; i<maxn; i++)
 31     {
 32         sum[i].clear();
 33         node[i].clear();
 34         tree[i].clear();
 35     }
 36 }
 37 
 38 int main ()
 39 {
 40     int n, m;
 41     while (scanf ("%d %d", &n, &m) != EOF)
 42     {
 43         init (n);
 44         for (int i=2; i<=n; i++)
 45         {
 46             int v;
 47             scanf ("%d", &v);
 48             tree[v].push_back(i);
 49         }
 50         
 51         dfs (1);
 52         scanf ("%s", str+1);
 53         for (int i=1; i<=n; i++)
 54         {
 55             int size = node[i].size();
 56             for (int j=0; j<size; j++)
 57             {
 58                 sum[i].push_back(0);
 59                 int x = str[rp[node[i][j]]] - 'a';
 60                 sum[i][j] |= (1<<x);
 61             }
 62             for (int j=1; j<size; j++)
 63                 sum[i][j] ^= sum[i][j-1];
 64         }
 65         
 66         int x, h;
 67         while (m --)
 68         {
 69             scanf ("%d %d", &x, &h);
 70             int l, r, size;
 71             l = L[x];
 72             r = R[x];
 73             size = node[h].size();
 74             
 75             if (dep[x]>=h || !size || r<node[h][0] || l>node[h][size-1])
 76             {
 77                 printf ("Yes\n");
 78                 continue;
 79             }
 80             
 81             int a = lower_bound(node[h].begin(), node[h].end(), l) - node[h].begin();
 82             int b = lower_bound(node[h].begin(), node[h].end(), r) - node[h].begin();
 83             
 84             if (b == size || node[h][b]>r)
 85                 b --;
 86             int res = sum[h][b];
 87             if (a)
 88                 res ^= sum[h][a-1];
 89                 
 90             int ans = 0;
 91             for (int i=0; i<26; i++)
 92             {
 93                 if (res & (1<<i))
 94                     ans ++;
 95             }
 96             
 97             printf ("%s\n", ans>1?"No":"Yes");
 98         }
 99     }
100     return 0;
101 }

 

posted @ 2015-08-16 18:23  罗茜  阅读(166)  评论(0编辑  收藏  举报