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. LeetCode | Single Number II【转】

    题目:Given an array of integers, every element appears three times except for one. Find that single on ...

  2. Final-阶段站立会议4

    组名:天天向上 组长:王森 组员:张政.张金生.林莉.胡丽娜 代码地址:HTTPS:https://git.coding.net/jx8zjs/llk.git SSH:git@git.coding.n ...

  3. Python格式化字符串

    在编写程序的过程中,经常需要进行格式化输出,每次用每次查.干脆就在这里整理一下,以便索引. 格式化操作符(%) "%"是Python风格的字符串格式化操作符,非常类似C语言里的pr ...

  4. do put in ruby

    apikey: XO.apikeys.cms, data: { favoriteItems: [{ UserId: SaveToFavoriteVar.content.FavoriteItem.Use ...

  5. 【C51】UART串口通信

    我们常需要单片机和其他模块进行通信,数据传输,常用的方式就是串口通信技术. 常用来 单片机<-->电脑,  单片机<-->单片机之间通信. 串行通信 versus 并行通信 并 ...

  6. Android百分比布局支持库介绍——com.android.support:percent(转)

    转载自http://www.apkbus.com/forum.php?mod=viewthread&tid=244752&extra=&_dsign=0b699c42 在此之前 ...

  7. Java学习-001-JDK安装配置

    本节主要讲述在 Win7 64bit 系统下安装.配置 JDK8u25,敬请参阅.详细步骤如下: 一.JDK下载 您可到 官方网站 或 我的云盘 下载,对应的JDK8u25的安装程序,下载过程不再赘述 ...

  8. TCP三次握手四次挥手详解

    转载 http://www.cnblogs.com/zmlctt/p/3690998.html 相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需 ...

  9. cocos2dx 3.x(TexturePacker进行图片加密)

    游戏开发过程中要涉及到大量的图片,使用TexturePacker可以把小图合成大图.这是我们使用最多的功能,但是TexturePacker还带有对图片加密的功能.之前还是对加密不慎了解,所以写下来分享 ...

  10. 使用inherit属性值继承其父元素样式来覆盖UA自带样式。

    像button.input这样的表单控件,不同的浏览器都会有自己的样式风格(UA样式).我们可以使用inherit继承其父元素样式,从而覆盖浏览器的UA样式. button, input, selec ...