题目

这题目名字怎么这么长

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」的更多相关文章

  1. 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,求每个子树中最长的边,满 ...

  2. 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 思路: 树上启发式合并 从根节点出发到每个位置的每个字符的奇偶性记为每个位 ...

  3. 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的 ...

  4. 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 ...

  5. 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 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

  6. 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 ...

  7. 重学 Java 设计模式:实战备忘录模式「模拟互联网系统上线过程中,配置文件回滚场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 实现不了是研发的借口? 实现不了,有时候是功能复杂度较高难以实 ...

  8. 「CF741D」Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    传送门 Luogu 解题思路 考虑把22个字符状压下来,易知合法情况就是状态中之多有一个1,这个可以暴力一点判断23次. 然后后就是 dsu on the tree 了. 细节注意事项 咕咕咕 参考代 ...

  9. CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(DSU on tree)

    题目大意: 给定一个以1为根的树,每条路径上都有一个字符(a~v共22个)询问对于每一个子树内最长的路径上字母经排序后可以形成回文串的最长路径多长 解题思路: 假定给你一个字符串,如何判定其经打乱能否 ...

随机推荐

  1. 文件夹操作之判断是否存在(Directory)

    Directory类用于操作文件夹,用于创建.移动和枚举目录和子目录的静态方法.DirectoryInfo类用于典型操作,如复制,移动,重命名,创建和删除目录.他们都可用于获取和设置相关属性或有关创建 ...

  2. 对datatable添加数据

    DataTable dt = new DataTable(); dt.Columns.Clear(); dt.Columns.Add("事故发生时间"); dt.Columns.A ...

  3. 01.CLR的执行模型

    在非托管的C/C++中,可以进行一些底层的操作     "公共语言运行时"(CLR)是一个可由多种编程语言使用的"运行时"          CLR的核心功能包 ...

  4. [javaSE] 多线程(join方法)

    多条线程并发执行,随机切换,调用join()方法,会使当前线程所在的线程(一般主线程)冻结,直到当前线程结束,所在的线程才恢复继续执行 class JoinTestDemo implements Ru ...

  5. sql = 和<>遵循的sql-92标准的设置SET ANSI_NULLS ON

    说明 SQL-92 标准要求在对空值进行等于 (=) 或不等于 (<>) 比较时取值为 FALSE. 当 SET ANSI_NULLS 为 ON 时,即使 column_name 中包含空 ...

  6. 5 springboot 集成dubbo

    Apache Dubbo 是一款高性能Java RPC框架 由阿里巴巴开源并进入Apache孵化器,官网 http://dubbo.apache.org 提供服务化基础功能: 接口远程调用,智能负载均 ...

  7. float失效的情况

    前言:在最近的笔试中,两次碰到类似的问题,什么情况下float会失效?我目前知道的有2种: 1)display:none: 2)position:absolute.fixed. (1)display: ...

  8. .net reflector+reflexil修改编译后的dll文件

    1.用reflector打开相关的dll文件. 2.如果reflector中没有reflexil插件,点击工具栏中的Tools->Add-Ins 3.找到需要修改的文件,双击打开该文件:点击To ...

  9. C#-创建并添加TXT文件

    public static void WriteToText(string txtContent, string txtPath) { using (FileStream fs = new FileS ...

  10. LeetCode赛题515----Find Largest Element in Each Row

    问题描述 You need to find the largest element in each row of a Binary Tree. Example: Input: 1 / \ 2 3 / ...