A tree was planted in Rome, and there were n dots on the tree. Each point has a lowercase English letter. Number 1th is the root of the tree, and the rest of the n-1 has a father. Point and father are connected by a side. The father of the first point is pi, and pi<i.
The depth of a point is the number of points that pass through the path from the root to the current point. The depth of the root is 1.
U in the subtree of V, when and only if you walk in the root direction you can reach V. In particular, V is also in the subtree of v.
Rome to you. m query, the first I query contains two integer vi,hi. The node is now collected in the VI subtree and the depth is hi. Determine if rearranging these nodes can form a palindrome.
Sample explanation:
A string s is a palindrome, when and only when he is reading and reading against the same. The empty string is also a palindrome.
In the first query, point 1 contains z, which can constitute a palindrome.
The second query midpoint 5 and 6 contains c,d, which does not constitute a palindrome.
In the third query, there is no point in depth 4, which consists of an empty string.
In the fourth query, it also forms an empty string.
In the fifth query, the 2,3,4 conforms to the query criteria and contains the letter a,c,c. can form a CAC.
Input
A single set of test data. The
first row contains two N, M (1≤n,m≤500000) that represents the number of nodes and the number of queries in the tree.
the second line has n-1 digital P2,P3,..., pn, representing every point of the father. (1≤pi<i).
The next line has n lowercase letters, and the first one represents the letters above the first point.
Next, each row of the M line has a query that contains VI, HI (1≤vi,hi≤n), which represents the point number and depth.
Output
For each query, if you can form a palindrome, output yes, otherwise output No.
Input sample
6 5
1 1 1 3 3
ZACCCD
1 1
3
3 4
1 6 1 1-2
Output sample
Yes
No
Yes
Yes
Yes
#include <iostream> #include <vector> #include <cstring> #include <algorithm> #include <
Cstdio> using namespace std;
const int MAXN = 5e5 + 10;
struct Node {node (int i, int h) {index = i;
Height = h;
} int index;
int height;
};
int n, m;
Vector<int> CHILD[MAXN];
Vector<node> BUF[MAXN];
Char VAL[MAXN];
void Dfs (vector<int> &parent, int pos, int h) {parent.push_back (POS);
Node Temp (POS, H + 1);
for (int i = 0; i < parent.size (); i++) {buf[parent[i]].push_back (temp);
for (int i = 0; i < child[pos].size (); i++) {DFS (parent, child[pos][i], H + 1);
} parent.pop_back ();
} Char num[26];
BOOL Valid () {int count = 0;
for (int i = 0; i < i++) {if (Num[i] & 1) {count++;
} if (Count > 1) {return false;
return true; BOOL CMP (cOnst Node A, const node B) {return a.height < b.height;}
int leftmost (vector<node> &a, int h) {int left = 0;
int right = A.size ()-1;
while (left < right-1) {int mid = left + (right-left)/2;
if (A[mid].height < h) {left = mid;
else {right = Mid;
} if (a[left].height = = h) {return left;
else if (A[right].height = h) {return right;
} return-1;
int rightmost (vector<node> &a, int h) {int left = 0;
int right = A.size ()-1;
while (left < right-1) {int mid = left + (right-left)/2;
if (A[mid].height > H) {right = Mid;
else {left = mid;
} if (a[right].height = = h) {return right; else if (A[left].height = h) {return left;
} return-1;
} template <class t> inline void Scan_d (T &ret) {char C;
ret = 0;
while ((c = GetChar ()) < ' 0 ' | | | c > ' 9 ');
while (c >= ' 0 ' && C <= ' 9 ') {ret = ret * + (C-' 0 '), C = GetChar ();
int main () {Scan_d (n);
Scan_d (m);
int A;
for (int i = 2; I <= n; i++) {Scan_d (a);
Child[a].push_back (i);
} scanf ("%s", &val[1]);
Vector<int> parent;
DFS (parent, 1, 0);
for (int i = 1; I <= n; i++) {sort (Buf[i].begin (), Buf[i].end (), CMP);
int V, h;
for (int i = 0; i < m; i++) {Scan_d (v);
Scan_d (h);
int left = leftmost (Buf[v], h);
if (left < 0) {puts ("Yes");
Continue
int right = rightmost (Buf[v], h);
memset (num, 0, sizeof (num));
for (int j = left; J <= right; J +) { int value = Val[buf[v][j].index]-' a ';
num[value]++;
} if (valid ()) {puts ("Yes");
else {puts ("No");
} return 0; }