codeforces 570D
Posted uuzlove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 570D相关的知识,希望对你有一定的参考价值。
一个字符串能重排成回文串等价于这个字符串最多只有一个字符出现次数为奇数次
这题的询问和子树中深度有关,那么显然可以用dsu on tree解决
把询问离线下来挂在点上,然后按dsu on tree的顺序统计子树信息即可
复杂度(O(nlogn+26m))
1 #include<bits/stdc++.h> 2 #define maxn 500005 3 using namespace std; 4 int n,m; 5 char s[maxn]; 6 vector<int> g[maxn]; 7 int sz[maxn],wson[maxn],d[maxn]; 8 void dfs(int u) 9 { 10 sz[u]=1; 11 for(int v:g[u]) 12 { 13 d[v]=d[u]+1; 14 dfs(v); 15 sz[u]+=sz[v]; 16 if(sz[v]>sz[wson[u]])wson[u]=v; 17 } 18 } 19 int has[maxn][26]; 20 vector<pair<int,int>> qry[maxn]; 21 int Ans[maxn]; 22 void add(int u,int x) 23 { 24 has[d[u]][s[u]-‘a‘]+=x; 25 for(int v:g[u])add(v,x); 26 } 27 void solve(int u) 28 { 29 has[d[u]][s[u]-‘a‘]++; 30 for(int v:g[u])if(v!=wson[u]) 31 { 32 solve(v); 33 add(v,-1); 34 } 35 if(wson[u])solve(wson[u]); 36 for(int v:g[u])if(v!=wson[u])add(v,1); 37 for(auto pa:qry[u]) 38 { 39 int dep=pa.first,id=pa.second; 40 int num=0; 41 for(int j=0;j<26;++j)if(has[dep][j]&1)num++; 42 if(num<=1)Ans[id]=1;else Ans[id]=0; 43 } 44 } 45 int main() 46 { 47 scanf("%d%d",&n,&m); 48 for(int x,i=2;i<=n;++i) 49 { 50 scanf("%d",&x); 51 g[x].push_back(i); 52 } 53 scanf("%s",s+1); 54 for(int i=1;i<=m;++i) 55 { 56 int u,x; 57 scanf("%d%d",&u,&x); 58 qry[u].push_back(make_pair(x,i)); 59 } 60 d[1]=1;dfs(1); 61 solve(1); 62 for(int i=1;i<=m;++i)if(Ans[i])puts("Yes");else puts("No"); 63 }
以上是关于codeforces 570D的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 570D TREE REQUESTS dfs???+????????????
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段