原题
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 p**i, the parent index is always less than the index of the vertex (i.e., (p_i< 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 (v_i), (h_i). Let's consider the vertices in the subtree (v_i) located at depth (h_i). 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 n, m (1 ≤ n, m ≤ 500 000) — the number of nodes in the tree and queries, respectively.
The following line contains n - 1 integers (p_2, p_3, ..., p_n) — the parents of vertices from the second to the n-th (( 1≤ p_i < 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 v**i, (h_i) ((1 ≤ v_i, h_i ≤ n)) — the vertex and the depth that appear in the i-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".
思路
dsu裸题,根据dfs序确定其子树需要更新的范围
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#define LL long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f
#define PI 3.1415926535898
#define F first
#define S second
#define endl '
'
#define lson rt << 1
#define rson rt << 1 | 1
#define lowbit(x) (x & (-x))
#define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _per(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int maxn = 5e5 + 7;
int n, m, tot;
int son[maxn], sz[maxn], col[maxn], dpth[maxn], in[maxn], out[maxn], ans[maxn], id[maxn];
int cnt[maxn][30];
vector<int> G[maxn];
vector<pair<int, int>> q[maxn];
inline void add(int u, int val)
{
cnt[dpth[u]][col[u]] += val;
}
inline void update(int u, int val)
{
_rep(i, in[u], out[u]) add(id[i], val);
}
inline int check(int u, int dep)
{
int num = 0;
_rep(i, 1, 26)
{
num += cnt[dep][i] % 2;
}
return num <= 1;
}
inline void dfs(int u, int f, int dep)
{
in[u] = ++tot;
id[tot] = u;
sz[u] = 1;
dpth[u] = dep;
f(i, 0, G[u].size())
{
int v = G[u][i];
if (v == f)
continue;
dfs(v, u, dep + 1);
sz[u] += sz[v];
if (sz[v] > sz[son[u]])
son[u] = v;
}
out[u] = tot;
}
inline void dfs2(int u, int f, int op)
{
f(i, 0, G[u].size())
{
int v = G[u][i];
if (v == f)
continue;
if (v != son[u])
dfs2(v, u, 0);
}
if (son[u])
dfs2(son[u], u, 1);
f(i, 0, G[u].size())
{
int v = G[u][i];
if (v == son[u] || v == f)
continue;
update(v, 1);
}
add(u, 1);
f(i, 0, q[u].size()) ans[q[u][i].S] = check(u, q[u][i].F);
if (!op)
update(u, -1);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int x, y;
cin >> n >> m;
_rep(i, 2, n)
{
cin >> x;
G[x].push_back(i);
G[i].push_back(x);
}
char c;
_rep(i, 1, n)
{
cin >> c;
col[i] = c - 'a' + 1;
}
_rep(i, 1, m)
{
cin >> x >> y;
q[x].push_back({y, i});
}
dfs(1, -1, 1);
dfs2(1, -1, 0);
_rep(i, 1, m)
{
if (ans[i])
cout << "Yes" << endl;
else
cout << "No" << endl;
}
}