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 ...
随机推荐
- C语言程序设计II—第九周教学
第九周教学总结(22/4-28/4) 教学内容 本周的教学内容为: 9.1 输出平均分最高的学生信息 知识点:结构的概念.结构的定义形式.结构的嵌套定义.结构变量和结构成员变量的引用.重难点:结构变量 ...
- SkylineGlobe的PopupMessage里面嵌入的网页如何与主页面交互通讯
1.主页面调用PopupMessage,如果需要传值,就是普通的页面间的传值就可以实现了. a.html页面调用PopupMessage创建方法,url传入b.html?x=111&y=22; ...
- ESP8266开发综合篇(LUA开发-视频教程总揽)
为了解决基础教程简单入门但不实用,项目方案非常实用但比较难的问题,开始推出8266开发综合篇 综合篇涉及到AT,LUA,SDK,LUA(sdk)开发,LUA和SDK开发会同步进行,后期再整理AT指令的 ...
- python运算符基础实例
# encoding=utf-8 #两个数字相加 sumNumber=1+2 print(sumNumber) #输出结果:3 #两个字符串相加 sumString="Nice work&q ...
- DNS 协议
DNS 入门 域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务.它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网.DNS 使用 T ...
- C# 枚举基本用法及扩展方法
没什么好说的,都是些基础! 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; usi ...
- ActiveMQ在C#中的应用
本文是在.NET Framework框架下的应用,截止到目前ActiveMQ还不支持.NET Core,而RabbitMQ已经支持.NET Core,希望ActiveMQ能尽快支持. ActiveMQ ...
- Opencv 2.4.10 +VS2010 项目配置
资料来源:http://blog.csdn.net/scottly1/article/details/40978625
- 【JUC源码解析】CompletableFuture
简介 先说Future, 它用来描述一个异步计算的结果.isDone方法可以用来检查计算是否完成,get方法可以用来获取结果,直到完成前一直阻塞当前线程,cancel方法可以取消任务.而对于结果的获取 ...
- [译]通往 Java 函数式编程的捷径
原文地址:An easier path to functional programming in Java 原文作者:Venkat Subramaniam 译文出自:掘金翻译计划 以声明式的思想在你的 ...