标签:
题目链接:
题目描述:
给出一棵树,有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 }
codeforces 570 D. Tree Requests (dfs)
标签:
原文地址:http://www.cnblogs.com/alihenaixiao/p/4734724.html