子树,所以只要求出在s[v] e[v]之间的值,用二分的方法,找出起始结点的位置,和离开结点的位置用结束时的状态异或开始的状态,就可以求出来这个结点子树的状态了。复杂度由于要二分查找,为o(n * log(n);但离线的做法,更加有意义。
?
?
#define N 500005
#define M 100005
#define maxn 205
#define MOD 1000000000000000007
int n,m,tree[N],t,v,h,ans,s[N],e[N],index;
char str[N];
bool vis[N];
vector
p[N];
vector
dep[N]; int DFS(int f,int depth){ s[f] = index++; FI(p[f].size()){ DFS(p[f][i],depth + 1); } dep[depth].push_back(mp(index,dep[depth].back().second^(1<<(str[f - 1] - 'a')))); e[f] = index++; return 0; } int main() { while(S2(n,m)!=EOF) { FI(n + 1){ p[i].clear(); dep[i].clear(); dep[i].push_back(mp(0,0)); } FI(n-1){ S(t); p[t].push_back(i+2); } SS(str); index = 1; DFS(1,1); FI(m){ S2(v,h); int l = lower_bound(dep[h].begin(),dep[h].end(),mp(s[v],-1)) - dep[h].begin() - 1; int r = lower_bound(dep[h].begin(),dep[h].end(),mp(e[v],-1)) - dep[h].begin() - 1; ans = dep[h][r].second ^ dep[h][l].second; if(ans & (ans - 1)) printf(No ); else printf(Yes ); } } return 0; }
?