「CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths」
这题目名字怎么这么长
zky学长讲过的题
非常显然,就是重排之后能形成回文串的话,最多只能有一个字母出现奇数次
又发现这个字符集大小只有\(22\),于是套路的使用状压,把每一条边转化成一个二进制数,求一下根路径前缀异或和
由于异或的性质,我们想得到路径\((x,y)\)的异或值,只需要\(pre_x \bigoplus pre_y\)就可以了
于是我们\(dsu\ on\ tree\),统计一个子树里所有的\(pre\)之后枚举一下拼成什么就好了
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define LL long long
#define re register
#define maxn 500005
inline int read() {
int x=0;char c=getchar();while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int n,num,Son,ans;
struct E{int v,nxt,w;}e[maxn];
int head[maxn],pre[maxn],deep[maxn],mx[5000005],vis[5000005];
int sum[maxn],son[maxn],Ans[maxn];
inline void add(int x,int y,int z) {e[++num].v=y;e[num].w=z;e[num].nxt=head[x];head[x]=num;}
void dfs1(int x) {
sum[x]=1;int maxx=-1;
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]) continue;
deep[e[i].v]=deep[x]+1;pre[e[i].v]=pre[x]^e[i].w;
dfs1(e[i].v);sum[x]+=sum[e[i].v];
if(sum[e[i].v]>maxx) maxx=sum[e[i].v],son[x]=e[i].v;
}
}
inline void ask(int x) {
if(vis[pre[x]]) ans=max(ans,deep[x]+mx[pre[x]]);
int now=pre[x];
for(re int i=0;i<22;i++)
if(vis[now^(1<<i)]) ans=max(ans,deep[x]+mx[now^(1<<i)]);
}
void calc(int x,int opt) {
if(opt==1) ask(x);
else mx[pre[x]]=0,vis[pre[x]]--;
for(re int i=head[x];i;i=e[i].nxt)
if(Son!=e[i].v) calc(e[i].v,opt);
}
void add(int x) {
mx[pre[x]]=max(mx[pre[x]],deep[x]);vis[pre[x]]++;
for(re int i=head[x];i;i=e[i].nxt) add(e[i].v);
}
void dfs(int x,int opt) {
for(re int i=head[x];i;i=e[i].nxt)
if(son[x]!=e[i].v) dfs(e[i].v,0);
if(son[x]) dfs(son[x],1);
Son=son[x],ans=0;ask(x);
mx[pre[x]]=max(mx[pre[x]],deep[x]);vis[pre[x]]++;
for(re int i=head[x];i;i=e[i].nxt)
if(son[x]!=e[i].v) calc(e[i].v,1),add(e[i].v);
Son=0;Ans[x]=ans-2*deep[x];
if(!son[x]) Ans[x]=0;
if(!opt) calc(x,0);
for(re int i=head[x];i;i=e[i].nxt) Ans[x]=max(Ans[x],Ans[e[i].v]);
}
int main() {
n=read();char ch;
for(re int fa,i=2;i<=n;i++)
fa=read(),ch=getchar(),add(fa,i,1<<(ch-'a'));
deep[1]=1,dfs1(1);dfs(1,1);
for(re int i=1;i<=n;i++) printf("%d ",Ans[i]);
return 0;
}
「CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths」的更多相关文章
- 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,求每个子树中最长的边,满 ...
- 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 思路: 树上启发式合并 从根节点出发到每个位置的每个字符的奇偶性记为每个位 ...
- 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的 ...
- 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 ...
- 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 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...
- CF 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 http://codeforces.com/problemset/probl ...
- 重学 Java 设计模式:实战备忘录模式「模拟互联网系统上线过程中,配置文件回滚场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 实现不了是研发的借口? 实现不了,有时候是功能复杂度较高难以实 ...
- 「CF741D」Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
传送门 Luogu 解题思路 考虑把22个字符状压下来,易知合法情况就是状态中之多有一个1,这个可以暴力一点判断23次. 然后后就是 dsu on the tree 了. 细节注意事项 咕咕咕 参考代 ...
- CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(DSU on tree)
题目大意: 给定一个以1为根的树,每条路径上都有一个字符(a~v共22个)询问对于每一个子树内最长的路径上字母经排序后可以形成回文串的最长路径多长 解题思路: 假定给你一个字符串,如何判定其经打乱能否 ...
随机推荐
- 0/1背包问题(DP)
Description 给定 n 个物品和一个背包.物品 i 的重量是 wi ,其价值为 vi ,背包的容量为 C .问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大? Input 输入 ...
- 关于vue.js父子组件数据传递
vue.js中使用props down,events up的原则进行父子组件间的通信,先来记录下props down,看个例子: <div id="app2"> < ...
- android 使用图片轮播图---banner 使用
转自:https://github.com/youth5201314/banner 使用步骤 Step 1.依赖banner Gradle dependencies{ compile 'com.you ...
- [javaEE] 控制浏览器缓存资源
浏览器有默认的缓存机制,不同的浏览器,缓存头是不一样的 设置编码,调用setContentType()方法,参数:”text/html;charset=utf-8” 关闭缓存,调用setHeader( ...
- 撩课-Web大前端每天5道面试题-Day9
1. 请用至少3中方式实现数组去重? 方法一: indexOf ,,,,,,,,]; function repeat1(arr){ ,arr2=[];i<arr.length;i++){ ){ ...
- JPA 实体映射
一.实体基本映射 /* * @Entity:将领域对象标注为一个实体,表示保存到数据库中 * @@Table:保存到数据库中表名,默认表名为类名,可通过name属性命名 * * */ @Entity ...
- 【C++并发实战】(三) std::future和std::promise
std::future和std::promise std::future std::future期待一个返回,从一个异步调用的角度来说,future更像是执行函数的返回值,C++标准库使用std::f ...
- 设计模式 UML & java code
A: 创造性模式 1. 工厂方法模式(FactoryMethod) 1.1 类图 1.2 代码1 public interface Pet { public String petSound(); } ...
- WinForm实现Rabbitmq官网6个案例-Topics
代码: namespace RabbitMQDemo { public partial class Topics : Form { private string exchangeName = &quo ...
- 浏览器根对象window之值为字符串的属性
1. string属性 1.1 origin window.origin使用返回的是当前网页的网址.打开百度首页,并在控制台中输入 window.origin 控制台中会输出"https:/ ...