您的位置:首页 > 产品设计 > UI/UE

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了(┭┮﹏┭┮重写大法好..........)

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: