码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 570D

时间:2020-02-10 13:37:02      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:dfs   div   std   pac   深度   c++   次数   auto   vector   

一个字符串能重排成回文串等价于这个字符串最多只有一个字符出现次数为奇数次

这题的询问和子树中深度有关,那么显然可以用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

标签:dfs   div   std   pac   深度   c++   次数   auto   vector   

原文地址:https://www.cnblogs.com/uuzlove/p/12290409.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!