Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
感觉dsu on tree一定程度上还是与点分类似的。考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可。
重排后可以变成回文串相当于出现奇数次的字母不超过1个。考虑dsu on tree,容易想到遍历时记录每种情况的最大深度,合并时类似点分的逐个计算贡献再合并即可。这里有个问题是得到某子树信息后,对于原来的根来说,这个信息还要再加上一个偏移量,但直接暴力显然复杂度就不对了。实际上维护信息过程中不断传递偏移量即可。
一开始就发现了这个题只开了256M,于是机智的开了个map,悲惨的T掉了。然而题面里深藏不露的说了一句字母范围在a~v。这啥思博题啊。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,a[N],p[N],fa[N],size[N],deep[N],son[N],len[N],ans[N],t,f[<<];
struct data{int to,nxt;
}edge[N];
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],len[y]=z,p[x]=t;}
void make(int k)
{
size[k]=;
for (int i=p[k];i;i=edge[i].nxt)
{
deep[edge[i].to]=deep[k]+;
make(edge[i].to);
size[k]+=size[edge[i].to];
if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to;
}
}
inline int rev(int x){return (<<)-^x;}
void update(int k,int x,int op)
{
if (op==) f[k]=max(f[k],x);
else f[k]=;
}
void add(int k,int x,int op)//对子树内统计信息时,偏移量为x
{
update(x,deep[k],op);
for (int i=p[k];i;i=edge[i].nxt)
add(edge[i].to,x^(<<len[edge[i].to]),op);
}
int calc(int k,int x)
{
int ans=f[x]+deep[k];
for (int i=;i<;i++) ans=max(ans,deep[k]+f[x^(<<i)]);
if (ans==deep[k]) ans=-N;
for (int i=p[k];i;i=edge[i].nxt)
ans=max(ans,calc(edge[i].to,x^(<<len[edge[i].to])));
return ans;
}
int dfs(int k)//获得的该子树信息的偏移量
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=son[k])
{
int delta=dfs(edge[i].to);
ans[k]=max(ans[k],ans[edge[i].to]);
add(edge[i].to,delta,-);
}
int delta=;
if (son[k])
{
delta=dfs(son[k])^(<<len[son[k]]);ans[k]=max(ans[k],ans[son[k]]);
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=son[k])
{
ans[k]=max(ans[k],calc(edge[i].to,delta^(<<len[edge[i].to]))-(deep[k]<<));
add(edge[i].to,delta^(<<len[edge[i].to]),);
}
}
ans[k]=max(ans[k],f[delta]-deep[k]);
for (int i=;i<;i++) ans[k]=max(ans[k],f[delta^(<<i)]-deep[k]);
update(delta,deep[k],);
return delta;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("741D.in","r",stdin);
freopen("741D.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<=n;i++)
fa[i]=read(),addedge(fa[i],i,getc()-'a');
deep[]=;make();
dfs();
for (int i=;i<=n;i++) printf("%d ",ans[i]);
return ;
}
Codeforces 741D 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 [题解]这 ...
- CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
一棵根为1 的树,每条边上有一个字符(a-v共22种). 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树中最长的Dokhtar-kosh路 ...
- 【cf741】D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
传送门 题意: 给出一颗以\(1\)为根的有根树,树边带有一个字符(\(a\)~\(v\))的信息. 输出对于每个结点,其子树内最长的简单路径并且满足边上的字符能够组成回文串. 思路: 显然最终的答案 ...
- 【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
题意:我们称一个字符串为周驿东串当且仅当重排它的字符可以组成一个回文串. 给出一个n个点的有根树,根为1,每条边上有一个从a到v的字符,求每个点的子树中所有简单路径可以组成的周驿东串中的最长长度. n ...
- CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(DSU on tree)
题目大意: 给定一个以1为根的树,每条路径上都有一个字符(a~v共22个)询问对于每一个子树内最长的路径上字母经排序后可以形成回文串的最长路径多长 解题思路: 假定给你一个字符串,如何判定其经打乱能否 ...
- 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 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...
- 【CF600E】Lomsat gelral(dsu on tree)
[CF600E]Lomsat gelral(dsu on tree) 题面 洛谷 CF题面自己去找找吧. 题解 \(dsu\ on\ tree\)板子题 其实就是做子树询问的一个较快的方法. 对于子树 ...
- 【Luogu U41492】树上数颜色——树上启发式合并(dsu on tree)
(这题在洛谷主站居然搜不到--还是在百度上偶然看到的) 题目描述 给一棵根为1的树,每次询问子树颜色种类数 输入输出格式 输入格式: 第一行一个整数n,表示树的结点数 接下来n-1行,每行一条边 接下 ...
- 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 ...
随机推荐
- 运行Android Studio自带模拟器报:Guest isn't online after 7 second...
今天在运行Android Studio自带的手机模拟器时,出现如下异常情况 : 解决办法: 1.打开Android Virtue Device Manager,点击编辑选项 2.点击show Adva ...
- 为什么建议php字符串使用单引号而不是双引号
不少php提升效率的tip,都有提到字符串使用单引号,这是为什么呢? 因为在单引号中,php直接认为它里头包含的就是个字符串.而双引号时,php会检测里头是否包含变量.这样如果是纯粹的字符串的话,双引 ...
- 理解maven中SNAPSHOT版本的作用
https://leokongwq.github.io/2017/08/24/understanding-maven-snapshot.html 一次针对现有的http服务开发了一个SNAPSHOT版 ...
- JaxbUtil转json转XML工具类
json转换为XML工具类 package com.cxf.value; import org.springframework.util.StringUtils; import javax.xml.b ...
- Linux下安装解压版(tar.gz)MySQL5.7
最近尝试在Linux中安装了解压版MySQL,期间查阅了许多博客.很多博客看得我很懵逼,因此记录下自己的安装过程,方便后续查阅. 环境说明:CentOs7.2 一.清理 ...
- zjoi2018 day1游记
咕咕咕 upd:看见有人贴上zhihu的问题,那个我早就看到了... 谴责一番题主 @gzy_cjoier 阅读量马上700没想到吧 既然这么火我挂个广告吧 永别,OI 听说有人催更??
- [C#]使用Windows Form开发的天气预报小工具
用C#编写的天气预报小工具 功能 1.查询中国省份.城市及地区三级的天气预报: 2.显示1-7天一周的天气预报及未来8-15天的天气预报: 3.能定制地区的天气预报. 界面 源代码: https:// ...
- spring boot 在不同环境下读取不同配置文件的一种方式
在工程中,通常有根据不同的环境读取不同配置文件的需求,对于spring boot 来说,默认读取的是application.yml 或者 application.properties.为了区分不同的环 ...
- Linux df du 命令
df 命令 检查磁盘空间占用情况(并不能查看某个目录占用的磁盘大小). 命令格式:df [option] -h 以容易理解的格式(给人看的格式)输出文件系统分区使用情况,例如 10kB.10MB.10 ...
- 2018年高教社杯全国大学生数学建模竞赛C题解题思路
题目 C题 大型百货商场会员画像描绘 在零售行业中,会员价值体现在持续不断地为零售运营商带来稳定的销售额和利润,同时也为零售运营商策略的制定提供数据支持.零售行业会采取各种不同方法来吸引更多的人成 ...