传送门:https://codeforces.com/contest/570/problem/D
题目大意:给一棵树,每个节点有一个字母,问节点v的深度为h的儿子节点的所有字母能否组成一个回文串(深度是对于整棵树)
很裸的一个树上合并,也可以使用二分来做
//919ms
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;
vector<int>e[maxn];
vector<pair<int,int>>query[maxn];
int sz[maxn],depth[maxn],st[maxn],ed[maxn],pre[maxn];
int cnt[maxn][26],cnt2[maxn];
bool ans[maxn];
char str[maxn];
int n,m,dfs_clock;
void dfs1(int u,int dp)
{
depth[u]=dp;
sz[u]=1;
st[u]=++dfs_clock;pre[dfs_clock]=u;
for(auto v:e[u]){
dfs1(v,dp+1);
sz[u]+=sz[v];
}
ed[u]=dfs_clock;
}
void add(int u,int val)
{
for(int i=st[u];i<=ed[u];i++){
int v=pre[i];
cnt[depth[v]][str[v]-'a']+=val;
if(cnt[depth[v]][str[v]-'a']&1) cnt2[depth[v]]++;
else cnt2[depth[v]]--;
}
}
void dfs2(int u,bool keep)
{
int maxx=-1,bigson=-1;
for(auto v:e[u]){
if(sz[v]>maxx){
maxx=sz[v];
bigson=v;
}
}
for(auto v:e[u]){
if(v==bigson) continue;
dfs2(v,false);
}
if(bigson!=-1) dfs2(bigson,true);
for(auto v:e[u])
if(v!=bigson) add(v,1);
cnt[depth[u]][str[u]-'a']++;
if(cnt[depth[u]][str[u]-'a']&1) cnt2[depth[u]]++;
else cnt2[depth[u]]--;
for(auto it:query[u]){
ans[it.second]=cnt2[it.first]<=1;
}
if(!keep) add(u,-1);
}
int main()
{
freopen("in","r",stdin);
freopen("out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++){
int v;
scanf("%d",&v);
e[v].push_back(i);
}
scanf("%s",str+1);
for(int i=1;i<=m;i++){
int v,h;
scanf("%d%d",&v,&h);
query[v].emplace_back(h,i);
}
dfs1(1,1);
dfs2(1,false);
for(int i=1;i<=m;i++)
if(ans[i]) puts("Yes");
else puts("No");
return 0;
}