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 ...
随机推荐
- java线程状态和获取线程基本信息
1. 线程状态 新生状态 用 new 关键字建立一个线程后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start()方法进入就绪状态. 就绪状态 处于就绪状态线程具备了运行 ...
- highcharts中数据列点击事件
Highcharts.chart('container', { xAxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul ...
- JDK 升级问题小结
JDK8 发布很久了,它提供了许多吸引人的新特性,能够提高编程效率. 如果是新的项目,使用 JDK8 当然是最好的选择.但是,对于一些老的项目,升级到 JDK8 则存在一些兼容性问题,是否升级需要酌情 ...
- PowerDesign 16.0 生成的SQL Server2000 数据库脚本时MS_Description不存在的问题解决
根据网上查询到的资料,找到了解决方法,原文出自:http://www.cnblogs.com/24tt/p/5047257.html PowerDesign 16.0 生成的Script语句,Sql2 ...
- 值类型和引用类型的区别,struct和class的区别
C#值类型和引用类型 1.简单比较 值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中. 值类型(value type):byte,short,int,long,floa ...
- Linux下FTP环境部署梳理(vsftpd和proftpd)
在日常运维工作中,常部署到的FTP是vsftpd和proftd.之前写了Linux下FTP虚拟账号环境部署总结,下面简单说下本地用户下的FTP环境部署过程: 简单梳理下FTP主动和被动两种工作模式: ...
- yum源使用的几个报错小总结 (例如: python2.6.6 下yum不能使用: No module named yum)
服务器上的yum突然不好使用,使用yum时有如下几个保持,解决方案如下: 1)Error: Cannot retrieve repository metadata (repomd.xml) for r ...
- Nginx入门【转】
原文地址:http://blog.csdn.net/u012486840/article/details/53098890 1.静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上 ...
- 10 分钟理解 BFC 原理
一.常见定位方案 在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案: 普通流 (normal flow) 在普通流中,元素按照其在 HTML 中的先后位置至 ...
- HTTP协议冷知识大全
如果不用HTTPS,HTTP协议如何安全的传输密码信息? HTTP协议是纯文本协议,没有任何加密措施.通过HTTP协议传输的数据都可以在网络上被完全监听.如果用户登陆时将用户名和密码直接明文通过HTT ...