【cf741】D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
题意:
给出一颗以\(1\)为根的有根树,树边带有一个字符(\(a\)~\(v\))的信息。
输出对于每个结点,其子树内最长的简单路径并且满足边上的字符能够组成回文串。
思路:
- 显然最终的答案分为两部分,子树内部的答案,经过当前根结点的答案。
- 第一种答案很好处理。类似于点分治,主要处理第二种答案。
- 树上路径可以考虑找到\(lca\),维护点到根节点的信息。
- 题目中的回文串可以等价于,出现奇数次的字符不超过\(1\)个。我们将字符状压一下,那么维护点到根的信息就很方便了;同理求出两点间的信息也很方便。
- 因为要枚举两条链中的结点,我们可以类似于树\(dp\)那样,保留之前的信息,然后枚举这条链更新答案并且更新信息。
- 这里显然枚举时枚举轻边最优(类似于启发式合并),那么可以采用\(dsu\ on\ tree\),算法会保留重儿子的信息,我们直接暴力轻儿子即可。
根据\(dsu\ on\ tree\)算法的思想,每个结点只会被暴力到\(O(logn)\)次,所以算法的时间复杂度为\(O(nlogn)\)。
感觉挺考察对\(dsu\ on\ tree\)的理解的。。细节见代码吧:
/*
* Author: heyuhhh
* Created Time: 2019/11/15 16:10:20
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 5e5 + 5;
int n;
char s[N];
vector <int> g[N];
int dis[N], sz[N], bson[N], d[N];
int f[1 << 22];
int ans[N];
void dfs(int u, int fa) {
sz[u] = 1;
int mx = 0;
d[u] = d[fa] + 1;
if(fa) dis[u] = (dis[fa] ^ (1 << (s[u] - 'a')));
for(auto v : g[u]) {
dfs(v, u);
sz[u] += sz[v];
if(sz[v] > mx) {
mx = sz[v]; bson[u] = v;
}
}
}
int Max, D;
void upd(int u) {
if(f[dis[u]]) Max = max(Max, f[dis[u]] + d[u] - D);
for(int i = 0; i < 22; i++) if(f[dis[u] ^ (1 << i)]) {
Max = max(Max, f[dis[u] ^ (1 << i)] + d[u] - D);
}
}
void upd2(int u) {
f[dis[u]] = max(f[dis[u]], d[u]);
}
void go(int u) {
upd(u);
for(auto v : g[u]) go(v);
}
void go2(int u) {
upd2(u);
for(auto v : g[u]) go2(v);
}
void clear(int u) {
f[dis[u]] = 0;
for(auto v : g[u]) clear(v);
}
void dfs2(int u, int fa, int op) {
for(auto v : g[u]) if(v != bson[u]) dfs2(v, u, 0);
if(bson[u]) dfs2(bson[u], u, 1);
for(auto v : g[u]) Max = max(Max, ans[v]);
D = 2 * d[u];
for(auto v : g[u]) if(v != bson[u]) {
go(v); go2(v);
}
upd(u); upd2(u);
ans[u] = Max;
if(!op) {
clear(u), Max = 0;
}
}
void run(){
for(int i = 2; i <= n; i++) {
int p;
scanf("%d %c", &p, &s[i]);
g[p].push_back(i);
}
dfs(1, 0);
dfs2(1, 0, 1);
for(int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
}
int main() {
while(cin >> n) run();
return 0;
}
【cf741】D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)的更多相关文章
- 【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 [题解]这 ...
- 【iOS】7.4 定位服务->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager(位置管理器)
本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...
- 【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
题意:我们称一个字符串为周驿东串当且仅当重排它的字符可以组成一个回文串. 给出一个n个点的有根树,根为1,每条边上有一个从a到v的字符,求每个点的子树中所有简单路径可以组成的周驿东串中的最长长度. n ...
- 【Telerik】实现列表单元格中添加复选框,进行状态(是、否)判断
前台界面: 需求:实现对每条细则是否必备进行判断,必备就勾选,否则不勾选. 首先:要保证列表GridView是可编辑的(IsReadOnly=false) 表格代码 其次:单元格的数据绑定要保证是双向 ...
- 【K8S】基于Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持续集成交付环境(环境搭建篇)
写在前面 最近在 K8S 1.18.2 版本的集群上搭建DevOps环境,期间遇到了各种坑.目前,搭建环境的过程中出现的各种坑均已被填平,特此记录,并分享给大家! 服务器规划 IP 主机名 节点 操作 ...
- Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...
- CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
一棵根为1 的树,每条边上有一个字符(a-v共22种). 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树中最长的Dokhtar-kosh路 ...
- 【翻译】Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)
[翻译]Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解) . . .
- 【原创】构建高性能ASP.NET站点 第五章—性能调优综述(后篇)
原文:[原创]构建高性能ASP.NET站点 第五章-性能调优综述(后篇) 构建高性能ASP.NET站点 第五章—性能调优综述(后篇) 前言:本篇主要讲述如何根据一些简单的工具和简单的现象来粗布的定位站 ...
随机推荐
- MySQL数据库:注释及数据类型
注释 /* 多行注释 */ # 单行注释 -- 单行注释(注意:两个但横线后面必须加空格) 数据类型 1.整形 tinyint.smallint.mediumint.int.bigint 小整 ...
- misc-3-1
无后缀,用winhex发现是rar,添加后缀解压,依据是无后缀,丢到kali,是一个流量数据包 TCP追踪流在第五个数据包发现flag.rar 导出对象 选择HTTP 找到flag.rar 然后丢到你 ...
- 201871010113-刘兴瑞《面向对象程序设计(java)》第七周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>htt ...
- js中var、let、const的区别 (待总结)
https://blog.csdn.net/qq_36784628/article/details/80966826 https://www.cnblogs.com/fly_dragon/p/8669 ...
- SqlServer PIVOT行转列
PIVOT通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合. 测试数据 INSERT INTO [TestRows2Columns] ...
- CentOS7下rsync服务端与Windows下cwRsync客户端实现数据同步配置方法
最近需求想定期备份服务器d盘的数据到Linux服务器上面,做个笔记顺便写下遇到的问题 以前整过一个win下的cwrsync(客户端)+rsync(服务端:存储)的bat脚本 和整过一个Linux下的r ...
- pytest框架之parametries数据驱动参数化
在测试用例的前面加上:@pytest.mark.parametrize('参数名', 列表数据) 参数名:用来接收每一项数据,并作为测试用例的参数 列表参数:一组测试数据(元组.列表.字典) 方式一: ...
- webwork遍历数组标签
WebWork中提供了一个<ww:iterator></ww:iterator>标签用于遍历数组. 01 如果数组中是普通类型,比如String.int等类型,可以通过标签中的 ...
- vscode打开文件在同一个tab的问题
当我们单击或者 cmd+鼠标左键单击打开文件时,有时候是在同一个窗口,有时候是新的窗口,这是啥样呢? 这是因为vscode有 "预览模式" , 当是预览模式时,打开的是当前窗口 ...
- Oracle - 截取指定日期的alert log
工作中DBA经常会查看alert log来检查数据库后台都记录了些什么日志,如果只想看某一天或者某段时间范围的日志,能够把这些日志从大的alert log中截取下来放到一个单独的文件中,对于查看和下载 ...