题意:
。。。
思路:
比赛的时候,想到dfs序,不过对层想不到好的处理方法。。
结束发现其实很简单。。分层统计不就行了吗。。
所以可以对每个询问,二分在层内的位置,也可以存前缀和,离线处理询问,甚至可以每一层都建一个BIT。。。
下面是离线处理的代码
注意题目的特殊条件,可以用异或来代替加减
const int N = 500005;
typedef pair<int, int> pii;
int n, m;
int L[N], R[N], D[N], vid[N];
vector<int> graph[N];
char s[N];
int timer = 0;
// u -> [ L[u], R[u] )
void dfs(int fa, int x, int dep) {
vid[timer] = x; L[x] = timer ++; D[x] = dep;
for (int v:graph[x]) dfs(x, v, dep + 1);
R[x] = timer;
}
int q[N][2];
bool cnt[N][26], sum[N][26], ans[N];
void solve(int m) {
vector<pii> tmp;
tmp.reserve(2*m);
rep(i, 1, m) {
int u, h;
scanf("%d%d", &u, &h);
-- u, -- h;
q[i][0] = u, q[i][1] = h;
tmp.push_back( make_pair(L[u], i) );
tmp.push_back( make_pair(R[u], -i) );
}
sort( tmp.begin(), tmp.end() );
int limi = tmp.size(), pre = 0;
rep(i, 0, limi-1) {
int pos = tmp[i].first, op = tmp[i].second;
//cout << " sweep " << "[ " << pre << ", " << pos << " ) " << op << endl;
rep(j, pre, pos - 1) {
int x = vid[j];
cnt[D[x]][s[x] - 'a'] ^= 1;
}
pre = pos;
int id = abs(op); int dep = q[id][1];
if ( op > 0 ) {
rep(j, 0, 25) sum[id][j] ^= cnt[dep][j];
} else {
int odd = 0;
rep(j, 0, 25) {
sum[id][j] ^= cnt[dep][j];
if ( sum[id][j] & 1 ) ++ odd;
//if ( sum[id][j] ) { char ch = j + 'a'; cout << ch << " : " << sum[id][j] << endl; }
}
//cout << "odd: " << odd << endl;
ans[id] = (odd < 2);
}
}
}
int main(){
#ifdef _LOCA_ENV_
freopen("input.in", "r", stdin);
#endif // _LOCA_ENV
scanf("%d%d", &n, &m);
rep(i, 1, n-1) {
int u;
scanf("%d", &u);
-- u;
graph[u].push_back(i);
}
scanf("%s", s);
dfs(-1, 0, 0);
solve(m);
rep(i, 1, m) {
if ( ans[i] )
puts("Yes");
else
puts("No");
}
return 0;
}