D. Tree Requests
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Roman planted a tree consisting of n vertices. Each vertex contains a lowercase English letter. Vertex 1 is the root of the tree, each of the n - 1 remaining vertices has a parent in the tree. Vertex is connected with its parent by an edge. The parent of vertex i is vertex pi, the parent index is always less than the index of the vertex (i.e., pi < i).

The depth of the vertex is the number of nodes on the path from the root to v along the edges. In particular, the depth of the root is equal to 1.

We say that vertex u is in the subtree of vertex v, if we can get from u to v, moving from the vertex to the parent. In particular, vertex v is in its subtree.

Roma gives you m queries, the i-th of which consists of two numbers vihi. Let's consider the vertices in the subtree vi located at depthhi. Determine whether you can use the letters written at these vertices to make a string that is a palindrome. The letters that are written in the vertexes, can be rearranged in any order to make a palindrome, but all letters should be used.

Input

The first line contains two integers nm (1 ≤ n, m ≤ 500 000) — the number of nodes in the tree and queries, respectively.

The following line contains n - 1 integers p2, p3, ..., pn — the parents of vertices from the second to the n-th (1 ≤ pi < i).

The next line contains n lowercase English letters, the i-th of these letters is written on vertex i.

Next m lines describe the queries, the i-th line contains two numbers vihi (1 ≤ vi, hi ≤ n) — the vertex and the depth that appear in thei-th query.

Output

Print m lines. In the i-th line print "Yes" (without the quotes), if in the i-th query you can make a palindrome from the letters written on the vertices, otherwise print "No" (without the quotes).

Examples
input
6 5
1 1 1 3 3
zacccd
1 1
3 3
4 1
6 1
1 2
output
Yes
No
Yes
Yes
Yes
Note

String s is a palindrome if reads the same from left to right and from right to left. In particular, an empty string is a palindrome.

Clarification for the sample test.

In the first query there exists only a vertex 1 satisfying all the conditions, we can form a palindrome "z".

In the second query vertices 5 and 6 satisfy condititions, they contain letters "с" and "d" respectively. It is impossible to form a palindrome of them.

In the third query there exist no vertices at depth 1 and in subtree of 4. We may form an empty palindrome.

In the fourth query there exist no vertices in subtree of 6 at depth 1. We may form an empty palindrome.

In the fifth query there vertices 2, 3 and 4 satisfying all conditions above, they contain letters "a", "c" and "c". We may form a palindrome "cac".

题意:给你一棵树,n个节点,m个询问;根节点为1;根结点的深度为1,

    每个节点含有一个权值;

    询问给你一个节点node,以node为根的子树中深度为x的结点,能否形成回文串;

思路:首先,能行成回文,只需要奇数的字母个数<=1;状态压缩标记即可;

   然后处理这课树,dfs序形成一个序列处理;

   对于m个询问, 两种思路:

   1:打表每个字母+深度进行存in[i](vector),然后m个询问复杂度o(26*(m*log(n));

   2:可以再广搜一遍,对于深度相同的必然是连续的一段序列,利用前缀异或和处理,复杂度(m*log(n));

   

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=5e5+,M=1e6+,inf=1e9+;
const ll INF=1e18+,mod=;
int in[N],out[N],tot,a[N],flag[N],deep[N];
struct is
{
int v,nex;
}edge[N<<];
int head[N<<],edg;
int n,p;
void init()
{
memset(head,-,sizeof(head));
memset(a,,sizeof(a));
edg=;
tot=;
}
void add(int u,int v)
{
edg++;
edge[edg].v=v;
edge[edg].nex=head[u];
head[u]=edg;
}
void dfs(int u,int fa,int d)
{
deep[u]=d;
in[u]=++tot;
for(int i=head[u];i!=-;i=edge[i].nex)
{
int v=edge[i].v;
if(v==fa)continue;
dfs(v,u,d+);
}
out[u]=tot;
}
char ch[N];
int root,x;
vector<int>ans[][N];
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
init();
for(int i=;i<=n;i++)
{
int v;
scanf("%d",&v);
add(i,v);
add(v,i);
}
dfs(,-,);
scanf("%s",ch+);
//for(int i=1;i<=n;i++)
// cout<<in[i]<<" "<<out[i]<<endl;
for(int i=;i<=n;i++)
flag[in[i]]=i;
for(int i=;i<=n;i++)
a[i]=deep[flag[i]];
for(int i=;i<=n;i++)
ans[ch[flag[i]]-'a'][a[i]].push_back(in[flag[i]]);
for(int i=;i<;i++)
{
for(int j=;j<=n;j++)
{
sort(ans[i][j].begin(),ans[i][j].end());
}
}
/*for(int i=0;i<26;i++)
{
for(int j=1;j<=n;j++)
{
cout<<j<<" ";
for(int k=0;k<ans[i][j].size();k++)
cout<<ans[i][j][k]<<" ";
cout<<endl;
}
cout<<"~~~~"<<endl;
}*/
while(q--)
{
scanf("%d%d",&root,&x);
if(deep[root]>=x)
{
printf("Yes\n");
continue;
}
int tot=;
for(int i=;i<;i++)
{
int pos1=lower_bound(ans[i][x].begin(),ans[i][x].end(),in[root])-ans[i][x].begin()-;
int pos2=upper_bound(ans[i][x].begin(),ans[i][x].end(),out[root])-ans[i][x].begin()-;
//cout<<pos1<<" "<<pos2<<endl;
tot+=(pos2-pos1)%;
}
if(tot>=)
printf("No\n");
else
printf("Yes\n");
}
}
return ;
}

Codeforces Round #316 (Div. 2) D. Tree Requests dfs序的更多相关文章

  1. Codeforces Round #316 (Div. 2) D Tree Requests

    官方题解是离线询问,dfs树形转线性,然后二分找区间. 还有一种比较好的做法是直接dfs,将当前访问这个结点u相关的询问之前的状态存起来,然后访问完以后利用异或开关性,得到这颗子树上的答案. 代码是学 ...

  2. Codeforces Round #316 (Div. 2) D. Tree Requests(dsu)

    题目链接 题意:对于m次询问 求解以vi为根节点 深度为hi的的字母能不能组合成回文串. 思路:暴力dsu找一边 简直就是神技! #include<bits/stdc++.h> #defi ...

  3. Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)

    https://codeforces.com/contest/1062/problem/E 题意 给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大.每次 ...

  4. Codeforces Round #646 (Div. 2) E. Tree Shuffling dfs

    题意: 给你n个节点,这n个节点构成了一颗以1为树根的树.每一个节点有一个初始值bi,从任意节点 i 的子树中选择任意k个节点,并按他的意愿随机排列这些节点中的数字,从而产生k⋅ai 的成本.对于一个 ...

  5. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  6. Codeforces 570D TREE REQUESTS dfs序+树状数组 异或

    http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...

  7. Codeforces Round #316 (Div. 2)

    A. Elections time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  8. Codeforces Round #268 (Div. 1) 468D Tree(杜教题+树的重心+线段树+set)

    题目大意 给出一棵树,边上有权值,要求给出一个1到n的排列p,使得sigma d(i, pi)最大,且p的字典序尽量小. d(u, v)为树上两点u和v的距离 题解:一开始没看出来p需要每个数都不同, ...

  9. Codeforces 570D TREE REQUESTS dfs序+树状数组

    链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...

随机推荐

  1. apache查看工作模式及调优

    一,查看工作模式 /usr/sbin/httpd -l Compiled in modules:  core.c  prefork.c  http_core.c  mod_so.c 如果出现prefo ...

  2. js串讲回顾

    注:1.xx.nextSibling.css.xxx->xx的下一个元素的css样式;2. window.opener.document.getElementById("cms&quo ...

  3. MVC控制器取参数值

    1.这个方法是获取提交表单里的参数值,也就是有name="xxx"的属性的表单控件的值 FormCollection传值 public ActionResult Login(For ...

  4. 安卓仿微信Tab页用Fragment实现

    最终效果图如: 实现步骤: 新建项目tabdemo,我选的是4.0.3版本,然后依次新建三个Fragment,名字分别为:ChatFragment.FriendFragment.FindFragmen ...

  5. 针对ajax执行后swiper特效无法执行解决方案

    ajax执行后重新绑定swiper事件.

  6. angularJs自定义指令.directive==类似自定义标签

    创建自定义的指令 除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTML 元素上需要添加自定义指令名 ...

  7. 加载UI

    weak情况 1 2 3 4 @property (weak,nonatomic) UILabel *nameLabel;   UILabel *nameLabel = [[UILabel alloc ...

  8. Python学习【第一篇】Python简介

    Python简介 Python前世今生 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. 现在,全世界差不多有600多种编 ...

  9. iOS: 上传App到AppStore,由于Xcode上传太慢,换成Application Loader上传,速度秒传

    一.遇到的遭遇 在之前的项目开发中,本人有点固执,一直采用xcode打包后再上传,结果可想而知: (1)要么上传时速度慢的跟蜗牛似的,等的我心力交瘁(不排除网络不给力的原因,公司这个吊问题快把我气疯了 ...

  10. SQLServer性能调优3之索引(Index)的维护

    前言 前一篇的文章介绍了通过建立索引来提高数据库的查询性能,这其实只是个开始.后续如果缺少适当的维护,你先前建立的索引甚至会成为拖累,成为数据库性能的下降的帮凶. 查找碎片 消除碎片可能是索引维护最常 ...