D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

http://codeforces.com/problemset/problem/741/D

题意:

  一棵根为1 的树,每条边上有一个字符(a-v共22种)。 求每个子树内的最长的路径,使得路径上的边按照一定顺序排列后是回文串。

分析:

  dsu on tree。询问子树信息。

  首先将这22个字符,转化为二进制。a=1,b=10,c=100...如果一条路径可以是回文串,那么要求路径的异或和最多有一个1。所以记录下从根到每个点的异或和,那么一条路径的异或和就是dis[u]^dis[v],lca上面的异或后消失了。

  之后维护每个子树内异或和为x的最大深度是多少。记为f。

  更新答案:按照点分治的思想,先更新不经过根的,然后求出经过根的(更新分成两步,第一步更新答案,第二步更新f数组。防止更新了在子树内部的)。

代码:

  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. using namespace std;
  12. typedef long long LL;
  13.  
  14. inline int read() {
  15. int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
  16. for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
  17. }
  18.  
  19. const int N = ;
  20.  
  21. int head[N], nxt[N], to[N], len[N], En;
  22. int fa[N], siz[N], son[N], dis[N], deth[N], ans[N];
  23. int f[( << ) + ];
  24. int Mx, D;
  25.  
  26. void add_edge(int u,int v,int w) {
  27. ++En; to[En] = v; len[En] = w; nxt[En] = head[u]; head[u] = En;
  28. }
  29.  
  30. void dfs(int u) {
  31. siz[u] = ;
  32. deth[u] = deth[fa[u]] + ;
  33. for (int i=head[u]; i; i=nxt[i]) {
  34. int v = to[i];
  35. fa[v] = u;
  36. dis[v] = dis[u] ^ ( << len[i]);
  37. dfs(v);
  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. if (f[dis[u]]) Mx = max(Mx, deth[u] + f[dis[u]] - D); // 异或后为0
  45. for (int i=; i<; ++i) // 异或后有一个1
  46. if (f[( << i) ^ dis[u]]) Mx = max(Mx, deth[u] + f[( << i) ^ dis[u]] - D);
  47. }
  48. void Calc(int u) { // 计算答案
  49. add(u);
  50. for (int i=head[u]; i; i=nxt[i]) Calc(to[i]);
  51. }
  52. void upd(int u) {
  53. f[dis[u]] = max(deth[u], f[dis[u]]);
  54. }
  55. void update(int u) { // 更新f数组
  56. upd(u);
  57. for (int i=head[u]; i; i=nxt[i]) update(to[i]);
  58. }
  59. void Clear(int u) {
  60. f[dis[u]] = ;
  61. for (int i=head[u]; i; i=nxt[i]) Clear(to[i]);
  62. }
  63.  
  64. void solve(int u,bool c) {
  65. for (int i=head[u]; i; i=nxt[i])
  66. if (to[i] != son[u]) solve(to[i], );
  67. if (son[u]) solve(son[u], );
  68.  
  69. D = deth[u] * ;
  70. for (int i=head[u]; i; i=nxt[i]) Mx = max(Mx, ans[to[i]]); //不经过根的
  71. for (int i=head[u]; i; i=nxt[i])
  72. if (to[i] != son[u]) Calc(to[i]), update(to[i]); // update(u) !!! 先更新答案,在更新f数组,(防止计算到在子树内部的路径)
  73. add(u); upd(u);
  74. ans[u] = Mx;
  75. if (!c) Clear(u), Mx = ;
  76. }
  77.  
  78. int main() {
  79. int n = read();
  80. char c[];
  81. for (int i=; i<=n; ++i) {
  82. int u = read(); scanf("%s", c);
  83. add_edge(u, i, c[] - 'a');
  84. }
  85. dfs();
  86. solve(, );
  87. for (int i=; i<=n; ++i) printf("%d ",ans[i]);
  88. return ;
  89. }

CF 741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths的更多相关文章

  1. CF 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths [dsu on tree 类似点分治]

    D. Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths CF741D 题意: 一棵有根树,边上有字母a~v,求每个子树中最长的边,满 ...

  2. Codeforces 741 D - Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    D - Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 思路: 树上启发式合并 从根节点出发到每个位置的每个字符的奇偶性记为每个位 ...

  3. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 好像这个题只能Dsu On Tree? 有根树点分治 统计子树过x的 ...

  4. codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    题目链接:Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 第一次写\(dsu\ on\ tree\),来记录一下 \(dsu\ o ...

  5. codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)

    codeforces 741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

  6. 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    [题意]给定n个点的树,每条边有一个小写字母a~v,求每棵子树内的最长回文路径,回文路径定义为路径上所有字母存在一种排列为回文串.n<=5*10^5. [算法]dsu on tree [题解]这 ...

  7. CF741 D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    题目意思很清楚了吧,那么我们从重排回文串的性质入手. 很容易得出,只要所有字符出现的次数都为偶数,或者有且只有一个字符出现为奇数就满足要求了. 然后想到什么,Hash?大可不必,可以发现字符\(\in ...

  8. [Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree

    题目链接: Codeforces741D 题目大意:给出一棵树,根为$1$,每条边有一个$a-v$的小写字母,求每个点子树中的一条最长的简单路径使得这条路径上的边上的字母重排后是一个回文串. 显然如果 ...

  9. Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...

随机推荐

  1. 理解JavaScript中的去抖函数

    何为去抖函数?在学习JavaScript去抖函数之前我们需要先弄明白这个概念.很多人都会把去抖跟节流两个概念弄混,但是这两个概念其实是很好理解的. 去抖函数(Debounce Function),是一 ...

  2. Intellij IDEA Organize Imports

    使用Eclipse进行开发时,我喜欢用Ctrl + Shift + O快捷键管理Java类的导入,它可以导入所需的Java类,去除不需要的Java类. Eclipse的Organize Imports ...

  3. 二十三、详述 IntelliJ IDEA 中恢复代码的方法「进阶篇」

    咱们已经了解了如何将代码恢复至某一版本,但是通过Local History恢复代码有的时候并不方便,例如咱们将项目中的代码进行了多处修改,这时通过Local History恢复代码就显得很麻烦,因为它 ...

  4. Redis(RedisTemplate)使用list链表

    RedisTemplate配置:https://www.cnblogs.com/weibanggang/p/10188682.html package com.wbg.springRedis.test ...

  5. HTML5对表单的一些有意思的改进

    HTML5对表单进行了许多的改进,在这篇文章中,我选择了其中个人认为很有趣的三个变化:自动聚焦,对button元素的改进,把表单元素与非父元素的form表单挂钩进行简单的介绍. 1. 自动聚焦 自动聚 ...

  6. JVM 内部原理

    1.JVM的组成: JVM 由类加载器子系统.运行时数据区.执行引擎以及本地方法接口组成. 2.JVM的运行原理: JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器.它是一种基 ...

  7. 双T滤波电路用于PWM方式DAC的分析

    双T滤波电路用于PWM方式DAC的分析   之前做温度控制的时候,用到了PWM到DAC的转化,PWM方波,经过滤波,怎么就变成了直流的信号,之前我也很困惑这一点.用频域的方法可以近似说明,但是严格的数 ...

  8. 确保img的宽高比固定

    html: <div class="wrapper"> <swiper :options="swiperOption"> <swi ...

  9. react系列(零)安装

    安装 在最初的阶段,可以使用在线编辑的网站来学习React基本的语法. 从 Hello World 开始,可以在Codepen,或者codesandbox上进行编写. 当然,也可以使用npm或者yar ...

  10. DQL-排序查询

    三:排序查询 语法: select  列名 from    表名 where  筛选条件 order by  需要排序的列名   asc/desc 特点:不写升序还是降序,默认升序 排序列表 可以是 ...