codeforces 570 D. Tree Requests (dfs)
2015-08-16 18:23
344 查看
题目链接:
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了(┭┮﹏┭┮重写大法好..........)
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了(┭┮﹏┭┮重写大法好..........)
#include <bits/stdc++.h> using namespace std; const int maxn = 500100; int L[maxn], R[maxn], rp[maxn]; int dfn, dep[maxn]; char str[maxn]; vector < int > sum[maxn]; vector < int > node[maxn]; vector < int > tree[maxn]; void dfs (int u) { L[u] = ++dfn; rp[L[u]] = u; node[dep[u]].push_back(L[u]); for (int i=0; i<tree[u].size(); i++) { int v = tree[u][i]; dep[v] = dep[u] + 1; dfs (v); } R[u] = dfn; } void init (int n) { dfn = 0; dep[1] = 1; for (int i=1; i<maxn; i++) { sum[i].clear(); node[i].clear(); tree[i].clear(); } } int main () { int n, m; while (scanf ("%d %d", &n, &m) != EOF) { init (n); for (int i=2; i<=n; i++) { int v; scanf ("%d", &v); tree[v].push_back(i); } dfs (1); scanf ("%s", str+1); for (int i=1; i<=n; i++) { int size = node[i].size(); for (int j=0; j<size; j++) { sum[i].push_back(0); int x = str[rp[node[i][j]]] - 'a'; sum[i][j] |= (1<<x); } for (int j=1; j<size; j++) sum[i][j] ^= sum[i][j-1]; } int x, h; while (m --) { scanf ("%d %d", &x, &h); int l, r, size; l = L[x]; r = R[x]; size = node[h].size(); if (dep[x]>=h || !size || r<node[h][0] || l>node[h][size-1]) { printf ("Yes\n"); continue; } int a = lower_bound(node[h].begin(), node[h].end(), l) - node[h].begin(); int b = lower_bound(node[h].begin(), node[h].end(), r) - node[h].begin(); if (b == size || node[h][b]>r) b --; int res = sum[h][b]; if (a) res ^= sum[h][a-1]; int ans = 0; for (int i=0; i<26; i++) { if (res & (1<<i)) ans ++; } printf ("%s\n", ans>1?"No":"Yes"); } } return 0; }
相关文章推荐
- 读《How quitting...》有感
- EasyUI----DataGrid 导出 Excel
- UIScrollView 实践经验
- android中的线程执行UI更新方式,以及Handler的初步了解
- UITableView优化技巧
- 问题解决:java.sql.SQLException:Value '0000-00-00' can not be represented as java.sql.Date
- atittit.表单验证性质的原则和实施,以及选择和定义自己的兼容easyui dsl窗体身份验证规则
- HDU 4908 BestCoder Sequence——BestCoder Round #3
- UVa 1584 - Circular Sequence
- Number Sequence(KMP,判断子串 模板)
- Team Queue(STL练习题)
- UIImage获取本地图片的方式对内存的影响
- Codeforces Round #316 (Div. 2) D. Tree Requests
- 【EasyUI】——可编辑的DataGrid
- hdu5288 OO’s Sequence
- LO Frequency Plan
- 解决Maven提示:Could not read settings.xml, assuming default values
- I/O复用--《APUE1》
- URAL1306 Sequence Median(卡内存神题)
- UILabel属性总结