cf570D Tree Requests
给一颗有根树,每个节点有一个字母,给m次询问,每次询问在i节点的子树下离根节点距离为d的所有节点的字母是否可以组合为回文串。
特别的,如果i节点下没有深度为d的节点都输出Yes。
我们统计每个节点下的子树所有深度的字母。用一个数组表示每个深度的26种字母。每次询问遍历26种字母如果总字母是奇数个且有两种及以上字母是出现了奇数次就肯定不能组合为回文串,偶数个字母必须都出现偶数次。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const int M = 5e5+7; int n,m,q,head[M],sz[M],son[M],cnt,depth[M],val[M],tot[M][27],ans[M]; char s[M]; vector<pair<int,int> > vec[M]; struct edge{ int v,next; }e[M<<1]; void init(){ cnt=0;memset(head,-1,sizeof(head)); } void add(int u,int v){ e[++cnt].v=v;e[cnt].next=head[u]; head[u]=cnt; } void dfs(int u,int fa,int dep){ sz[u]=1;son[u]=-1;depth[u]=dep; for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa) continue; dfs(v,u,dep+1); sz[u]+=sz[v]; if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v; } return ; } void addnode(int u){ tot[depth[u]][val[u]]++; } void delnode(int u){ tot[depth[u]][val[u]]--; } void addtree(int u,int fa){ addnode(u); for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa) continue; addtree(v,u); } } void deltree(int u,int fa){ delnode(u); for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa) continue; deltree(v,u); } } void dsu(int u,int fa){ for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa||v==son[u]) continue; dsu(v,u); deltree(v,u); } if(son[u]!=-1) dsu(son[u],u); for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa||v==son[u]) continue; addtree(v,u); } addnode(u); for(int i=0;i<vec[u].size();i++){ int h=vec[u][i].first,id=vec[u][i].second,flag=0,tmp=0;ans[id]=0; if(depth[u]>h){ ans[id]=1;continue; } for(int j=1;j<=26;j++){ if(tot[h][j]%2!=0) flag++; tmp+=tot[h][j]; } if(flag==0||(tmp%2!=0&&flag==1)) ans[id]=1; } } int main(){ init(); scanf("%d%d",&n,&m); for(int i=2;i<=n;i++){ int u; scanf("%d",&u); add(u,i); } scanf("%s",s); int l=strlen(s); for(int i=0;i<l;i++) val[i+1]=s[i]-'a'+1; dfs(1,-1,1); for(int i=1;i<=m;i++){ int u,h; scanf("%d%d",&u,&h); vec[u].push_back(make_pair(h,i)); } dsu(1,-1); for(int i=1;i<=m;i++){ if(ans[i]==1) printf("Yes\n"); else printf("No\n"); } return 0; }