D. Tree Requests
http://codeforces.com/problemset/problem/570/D
题意:
一个以1为根的树,每个点上有一个字母(a-z),每次询问一个子树内深度为h的点是否可以构成回文串。(深度是到1的深度,没有也算,空回文串)
分析:
dsu on tree。询问子树信息。
判断是否构成回文:出现奇数次的字符小于等于1个。
代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #define pa pair<int,int> 12 #define mp(a,b) make_pair(a,b) 13 using namespace std; 14 typedef long long LL; 15 16 inline int read() { 17 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 18 for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 19 } 20 21 const int N = 500005; 22 23 int head[N], nxt[N], to[N], En; 24 int fa[N], siz[N], son[N], deth[N], ans[N], cnt[N][27], ch[N]; 25 char s[N]; 26 vector< pa > q[N]; 27 28 void add_edge(int u,int v) { 29 ++En; to[En] = v; nxt[En] = head[u]; head[u] = En; 30 } 31 32 void dfs(int u,int fa) { 33 siz[u] = 1; 34 deth[u] = deth[fa] + 1; 35 for (int i=head[u]; i; i=nxt[i]) { 36 int v = to[i]; 37 dfs(v, u); 38 siz[u] += siz[v]; 39 if (!son[u] || siz[son[u]] < siz[v]) son[u] = v; 40 } 41 } 42 43 void add(int u) { 44 cnt[deth[u]][ch[u]] ++; 45 } 46 void Calc(int u) { 47 add(u); 48 for (int i=head[u]; i; i=nxt[i]) Calc(to[i]); 49 } 50 void Clear(int u) { 51 cnt[deth[u]][ch[u]] --; 52 for (int i=head[u]; i; i=nxt[i]) Clear(to[i]); 53 } 54 55 void solve(int u,bool c) { 56 for (int i=head[u]; i; i=nxt[i]) 57 if (to[i] != son[u]) solve(to[i], 0); 58 if (son[u]) solve(son[u], 1); 59 60 for (int i=head[u]; i; i=nxt[i]) 61 if (to[i] != son[u]) Calc(to[i]); 62 add(u); 63 64 for (int i=0,sz=q[u].size(); i<sz; ++i) { 65 int flag = 0, id = q[u][i].second, h = q[u][i].first; 66 for (int j=0; j<26; ++j) if (cnt[h][j] & 1) flag ++; 67 ans[id] = (flag <= 1); 68 } 69 70 if (!c) Clear(u); 71 } 72 73 int main() { 74 int n = read(), Q = read(); 75 for (int i=2; i<=n; ++i) { 76 int u = read(); 77 add_edge(u, i); 78 } 79 scanf("%s",s + 1); 80 for (int i=1; i<=n; ++i) ch[i] = s[i] - 'a'; 81 for (int i=1; i<=Q; ++i) { 82 int v = read(), h = read(); 83 q[v].push_back(mp(h, i)); 84 } 85 dfs(1, 0); 86 solve(1, 1); 87 for (int i=1; i<=Q; ++i) puts(ans[i] ? "Yes" : "No"); 88 return 0; 89 }