用深搜为每个结点建立一个时间序in[], out[],在搜索过程中把在同一深度,同一颜色结点的时间保存起来。查询的时候,若结点为v, 则所查询的所有节点的时间序在in[v]和out[v]之间,再用二分查找各个颜色结点个数。
#include <bits/stdc++.h>
#define maxn 500005
using namespace std;
vector<int> v[maxn];
vector<int> f[maxn][26];
int n, m;
string s;
int in[maxn], out[maxn], tot;
void dfs(int h, int x){
in[x] = ++tot;
f[h][s[x-1]-'a'].push_back(tot);
for(int i = 0; i < v[x].size(); i++)
dfs(h+1, v[x][i]);
out[x] = tot;
}
int main(){
// freopen("in.txt", "r", stdin);
int a;
scanf("%d%d", &n, &m);
for(int i = 2; i <= n; i++){
scanf("%d", &a);
v[a].push_back(i);
}
cin >> s;
tot = 0;
dfs(1, 1);
int v, h;
for(int i = 0; i < m; i++){
scanf("%d%d", &v, &h);
int p = 0;
for(int j = 0; j < 26; j++){
int d = upper_bound(f[h][j].begin(), f[h][j].end(), out[v]) -
lower_bound(f[h][j].begin(), f[h][j].end(), in[v]);
if(d&1)
p++;
if(p > 1)
break;
}
if(p > 1)
puts("No");
else
puts("Yes");
}
return 0;
}