[CF570D] Tree Requests(dsu on tree)

原题

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;
	}
}

原文地址:https://www.cnblogs.com/hfcdyp/p/14064184.html