[题目大意]:

给定一棵树,树的每个节点对应一个小写字母字符,有m个询问,每次询问以vi为根节点的子树中,深度为hi的所有节点对应的字符能否组成一个回文串;

[题目分析]:

先画个图,可看出每次询问的所有节点都是一个从1开始bfs遍历完成的节点序列中的一段,已知深度hi的情况下,可以二分得到深度为hi的那一段的位置;

那么如何满足找到的节点必须在以vi为根的子树内这个条件?

可以想到dfs的时间戳,把1-n的数组按深度排序,深度相同的按照dfs时间戳排序;

这样就可以二分得到要求的所有节点的位置;

这样可以O(n)

分析回文串可知,如果奇数数量的字符不超过1个,那么一定能组成回文串;

用前缀和xor优化;

可以做到O(nlogn);

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include<iomanip>
  7. #include<map>
  8. #include<set>
  9. #include<vector>
  10. #include<ctime>
  11. #include<cmath>
  12. using namespace std;
  13. #define LL long long
  14. #define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
  15. #define max(x,y) ((x)<(y)?(y):(x))
  16. #define min(x,y) ((x)<(y)?(x):(y))
  17. #define FILE "1"
  18. #define pii pair<int,int>
  19. const int maxn=,inf=;
  20. int read(){
  21. int x=;bool flag=;char ch=getchar();
  22. while(ch<''||ch>''){if(ch=='-')flag=;ch=getchar();}
  23. while(ch<=''&&ch>=''){x=x*+ch-'';ch=getchar();}
  24. return flag?-x:x;
  25. }
  26. struct node{
  27. int y,next;
  28. }e[maxn<<];
  29. int n,m;
  30. int linkk[maxn],len=,sum[maxn];
  31. int dfs_clock=,fa[maxn];
  32. char s[maxn];
  33. int f[maxn];
  34. struct Node{
  35. int dep,pre,lat,id;
  36. bool operator<(const Node &b)const{return dep<b.dep||(dep==b.dep&&pre<b.pre);}
  37. }a[maxn];
  38. void insert(int x,int y){
  39. e[++len].y=y;
  40. e[len].next=linkk[x];
  41. linkk[x]=len;
  42. }
  43. void dfs(int x){
  44. a[x].pre=++dfs_clock;a[x].id=x;
  45. for(int i=linkk[x];i;i=e[i].next){
  46. if(e[i].y==fa[x])continue;
  47. a[e[i].y].dep=a[x].dep+;
  48. dfs(e[i].y);
  49. }
  50. a[x].lat=++dfs_clock;
  51. }
  52. void init(){
  53. n=read(),m=read();int x;
  54. up(i,,n){
  55. x=read();
  56. insert(i,x);
  57. insert(x,i);
  58. fa[i]=x;
  59. }
  60. scanf("%s",s+);
  61. a[].dep=;
  62. dfs();
  63. sort(a+,a+n+);
  64. for(int i=;i<=n;i++)f[a[i].id]=i;
  65. }
  66. int find(int x,int Dep){
  67. int left=,right=n,mid;
  68. int L=,R=;
  69. while(left<=right){
  70. mid=(left+right)>>;
  71. if(a[mid].dep<Dep)left=mid+;
  72. else {
  73. right=mid-;
  74. if(a[mid].dep==Dep)L=mid;
  75. }
  76. }
  77. left=,right=n,mid=;
  78. while(left<=right){
  79. mid=(left+right)>>;
  80. if(a[mid].dep<=Dep){
  81. left=mid+;
  82. if(a[mid].dep==Dep)R=mid;
  83. }
  84. else right=mid-;
  85. }
  86. if(!L&&!R)return ;
  87. left=L,right=R;
  88. int u=,v=;
  89. while(left<=right){
  90. mid=(left+right)>>;
  91. if(a[mid].pre>=a[f[x]].pre){
  92. right=mid-;
  93. if(a[mid].pre>=a[f[x]].pre&&a[mid].pre<=a[f[x]].lat)u=mid;
  94. }
  95. else left=mid+;
  96. }
  97. left=L,right=R;
  98. while(left<=right){
  99. mid=(left+right)>>;
  100. if(a[mid].pre<=a[f[x]].lat){
  101. left=mid+;
  102. if(a[mid].pre>=a[f[x]].pre&&a[mid].pre<=a[f[x]].lat)v=mid;
  103. }
  104. else right=mid-;
  105. }
  106. if(!u||!v)return ;
  107. int p=sum[v]^sum[u-];
  108. int cnt=;
  109. while(p){
  110. if(p&)cnt++;
  111. p>>=;
  112. }
  113. if(cnt>=)return ;
  114. else return ;
  115. }
  116. void work(){
  117. int x,y;
  118. for(int i=;i<=n;i++)sum[i]=sum[i-]^(<<(s[a[i].id]-'a'));
  119. while(m--){
  120. x=read(),y=read();
  121. if(find(x,y))printf("Yes\n");
  122. else printf("No\n");
  123. }
  124. }
  125. int main(){
  126. init();
  127. work();
  128. return ;
  129. }

codeforces 570D.Tree Requests的更多相关文章

  1. Codeforces 570D - Tree Requests(树上启发式合并)

    570D - Tree Requests 题意 给出一棵树,每个节点上有字母,查询 u k,问以 u 为根节点的子树下,深度为 k 的所有子节点上的字母经过任意排列是否能构成回文串. 分析 一个数组 ...

  2. Codeforces 570D TREE REQUESTS dfs序+树状数组 异或

    http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...

  3. Codeforces 570D TREE REQUESTS dfs序+树状数组

    链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...

  4. Codeforces 570D - Tree Requests【树形转线性,前缀和】

    http://codeforces.com/contest/570/problem/D 给一棵有根树(50w个点)(指定根是1号节点),每个点上有一个小写字母,然后有最多50w个询问,每个询问给出x和 ...

  5. CodeForces 570D - Tree Requests - [DFS序+二分]

    题目链接:https://codeforces.com/problemset/problem/570/D 题解: 这种题,基本上容易想到DFS序. 然后,我们如果再把所有节点分层存下来,那么显然可以根 ...

  6. CF 570D. Tree Requests [dsu on tree]

    传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...

  7. codeforces 570 D. Tree Requests 树状数组+dfs搜索序

    链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...

  8. Codeforces Round #316 (Div. 2) D. Tree Requests dfs序

    D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. codeforces 570 D. Tree Requests (dfs)

    题目链接: 570 D. Tree Requests 题目描述: 给出一棵树,有n个节点,1号节点为根节点深度为1.每个节点都有一个字母代替,问以结点x为根的子树中高度为h的后代是否能够经过从新排序变 ...

随机推荐

  1. const T、const T*、T *const、const T&、const T*& 的区别

    原文地址: http://blog.csdn.net/luoweifu/article/details/45600415 这里的T指的是一种数据类型,可以是int.long.doule等基本数据类型, ...

  2. Java ArrayList 详解

    只记录目前为止关注的.JDK1.8 一.基础属性 1.1 内部参数 //空存储实例.直接new ArrayList()便是以该空数组作为实例 private static final Object[] ...

  3. Eval is evil ('Eval是魔鬼') --- eval()函数

    Eval is evil ('Eval是魔鬼') eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码.语法:eval(string): eval的使用场合是什么呢?有时候我 ...

  4. 1.【nuxt起步】-nuxt是什么?

    百度了解下,简单说就是vue的seo化,因为vue是spa,不支持seo,从本地运行的源码可以看出来,html没有tkd和相关文字,导致百度收录困难,所以nuxt可以很好的解决这个问题, 举个例子:纯 ...

  5. C++ 用libcurl库进行http通讯网络编程 【转】

    http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html C++ 用libcurl库进行http通讯网络编程 目录索引: 一.Lib ...

  6. 理解Neural Style

    paperA Neural Algorithm of Artistic Style 在艺术领域,尤其是绘画,艺术家们通过创造不同的内容与风格,并相互交融影响来创立独立的视觉体验.如果给定两张图像,现在 ...

  7. Java自定义注解和运行时靠反射获取注解

    转载:http://blog.csdn.net/bao19901210/article/details/17201173/ java自定义注解 Java注解是附加在代码中的一些元信息,用于一些工具在编 ...

  8. java性能监控工具jps-windows

    jps Lists the instrumented Java Virtual Machines (JVMs) on the target system. This command is experi ...

  9. Android——动画的分类

    Android包含三种动画:View Animation, Drawable Animation, Property Animation(Android 3.0新引入). 1.View Animati ...

  10. PHP工作模型与运行机制

    PHP的工作模型非常特殊.从某种程度上说,PHP和ASP.ASP.NET.JSP/Servlet等流行的Web技术,有着本质上的区别.   以Java为例,Java在Web应用领域,有两种技术:Jav ...