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 }
View Code

 

以上是关于codeforces 570D的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 570D TREE REQUESTS dfs???+????????????

CF570D:Tree Requests

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段

CF 570D Tree Requests

CF570D Tree Requests

CF570D Tree Requests