1.思路
对于这题来说,总的来说还是dsu的一个板子,我们计算完了之后暴力更新就好了.复杂度是O(26*nlogn)的.
2.代码
#include <bits/stdc++.h> using namespace std; const int N=5e5+50,M=26; struct DSU{ int id,k; }; vector<DSU>ask[N]; vector<int>v[N]; bool ans[N];//存询问的答案. char s[N]; int dep[N],sz[N],dfn[N],Son; int tot[M][N];//统计当前在深度为u时的s[i]个数. void cal(int u,int fa,bool op) { if(op) tot[s[u]-'a'][dep[u]]++; else tot[s[u]-'a'][dep[u]]--; for(int i=0;i<(int)v[u].size();i++) { int son=v[u][i]; if(son==fa||son==Son) continue; cal(son,u,op); } } void dfs(int u,int fa) { dep[u]=dep[fa]+1;sz[u]=1; for(int i=0;i<(int)v[u].size();i++) { int son=v[u][i]; if(son==fa) continue; dfs(son,u); sz[u]+=sz[son]; if(sz[son]>sz[dfn[u]]) dfn[u]=son; } } void dfs(int u,int fa,bool op) { //printf("%d\n",u); for(int i=0;i<(int)v[u].size();i++) { int son=v[u][i]; if(son==fa||son==dfn[u]) continue; dfs(son,u,true); } if(dfn[u]) dfs(dfn[u],u,false),Son=dfn[u]; cal(u,fa,true); for(int i=0;i<(int)ask[u].size();i++) { int id=ask[u][i].id; int Dep=ask[u][i].k; //printf("%d %d %dssss\n",id,u,Dep); int cnt=0; for(int j=0;j<26;j++) { if(tot[j][Dep]&1) cnt++; } //printf("%d %daaaa\n",id,cnt); if(cnt<2) ans[id]=1; } Son=0; if(op) { cal(u,fa,false); } } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=2;i<=n;i++) { int x;scanf("%d",&x); v[i].push_back(x); v[x].push_back(i); }dfs(1,0);scanf("%s",s+1); for(int i=1;i<=m;i++) { int u,x; scanf("%d%d",&u,&x); ask[u].push_back({i,x}); }dfs(1,0,0); for(int i=1;i<=m;i++) ans[i]==1?puts("Yes"):puts("No"); return 0; } /* 为什么题目写少了,连基本的验证答案都不会了. */