600E
板子
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int fa[N],son[N],siz[N];
struct Edge{
int to,next;
Edge(){}
Edge(int to,int next):to(to),next(next){}
}E[N];
int head[N],tot;
inline void addedge(int u,int v){
E[tot]=Edge(v,head[u]);
head[u]=tot++;
}
void dfs(int x,int f){
siz[x]=1,fa[x]=f;
for(int i=head[x];~i;i=E[i].next)if(E[i].to^f){
int v=E[i].to;
dfs(v,x);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]])son[x]=v;
}
}
ll Ans[N],maxans,ans;
int cnt[N],vis[N],col[N];
void add(int x,int p){
cnt[col[x]]+=p;
if(p>0&&cnt[col[x]]==maxans)ans+=col[x];
if(p>0&&cnt[col[x]]>maxans)maxans=cnt[col[x]],ans=col[x];
for(int i=head[x];~i;i=E[i].next)if(E[i].to^fa[x]&&!vis[E[i].to])add(E[i].to,p);
// !vis[E[i].to]就再遍历一遍轻儿子
}
void dfs2(int x,int p){//x子树根节点,p表示x是否是重儿子
for(int i=head[x];~i;i=E[i].next){
int v=E[i].to;
if(v^fa[x]&&v^son[x])dfs2(v,0);//遍历轻儿子
}
if(son[x])dfs2(son[x],1),vis[son[x]]=1;//遍历重儿子
add(x,1),Ans[x]=ans;//计算子树
if(son[x])vis[son[x]]=0;
if(!p)add(x,-1),ans=maxans=0;//是轻儿子,擦除
}
void init(){
tot=0,memset(head,-1,sizeof(head));
}
int n,u,v;
int main(){
init();
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",&col[i]);
for(int i=1;i< n;++i)scanf("%d%d",&u,&v),addedge(u,v),addedge(v,u);
dfs(1,0),dfs2(1,0);
for(int i=1;i<=n;++i)printf("%lld ",Ans[i]);
return 0;
}
570D
#include<bits/stdc++.h>
#define P(i,j) make_pair(i,j)
using namespace std;
typedef long long ll;
const int N=5e5+5;
int fa[N],son[N],siz[N],dep[N];
struct Edge{
int to,next;
Edge(){}
Edge(int to,int next):to(to),next(next){}
}E[N<<2];
int head[N],tot;
inline void addedge(int u,int v){
E[tot]=Edge(v,head[u]);
head[u]=tot++;
}
void dfs(int x,int f,int d){
siz[x]=1,fa[x]=f,dep[x]=d;
for(int i=head[x];~i;i=E[i].next)if(E[i].to^f){
int v=E[i].to;
dfs(v,x,d+1);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]])son[x]=v;
}
}
int cnt[N],col[N],vis[N],ans[N];
char s[N];
vector<pair<int,int> >query[N];
bool C(int x){//二进制几个1
x=(x&0x55555555)+((x&0xaaaaaaaa)>>1);
x=(x&0x33333333)+((x&0xcccccccc)>>2);
x=(x&0x0f0f0f0f)+((x&0xf0f0f0f0)>>4);
x=(x&0x00ff00ff)+((x&0xff00ff00)>>8);
x=(x&0x0000ffff)+((x&0xffff0000)>>16);
return x<=1;
}
void add(int x){//两次异或刚好消除影响
cnt[dep[x]]^=1<<(s[x]-'a');
for(int i=head[x];~i;i=E[i].next)if(E[i].to^fa[x]&&!vis[E[i].to])add(E[i].to);
}
void dfs2(int x,int p){
for(int i=head[x];~i;i=E[i].next){
int v=E[i].to;
if(v^fa[x]&&v^son[x])dfs2(v,0);
}
if(son[x])dfs2(son[x],1),vis[son[x]]=1;
add(x);
for(auto i:query[x])ans[i.second]=C(cnt[i.first]);
if(son[x])vis[son[x]]=0;
if(!p)add(x);
}
void init(){
tot=0,memset(head,-1,sizeof(head));
}
int n,u,v,m;
int main(){
init();
scanf("%d%d",&n,&m);
for(int i=2;i<=n;++i)scanf("%d",&v),addedge(v,i),addedge(i,v);
scanf("%s",s+1);
for(int i=1;i<=m;++i)scanf("%d%d",&u,&v),query[u].push_back(P(v,i));
dfs(1,0,1),dfs2(1,0);
for(int i=1;i<=m;++i)puts(ans[i]?"Yes":"No");
return 0;
}