本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

题目链接:CF741D

正解:$dsu$ $on$ $tree$

解题报告:

  对于这种回文串的问题,很显然出现次数为奇数的个数$<=1$,那么这个状态就可以状压了。

  用$S$表示从这个点到根的字母奇偶性情况,因为$<=1$,我们特判掉$0$之后就只需要考虑有一位的情况,枚举这一位,可以唯一地得到一个状态,来满足条件,那么就可以做了。

  考虑处理一个节点时,首先可以顺便处理掉从根到子树内某个点的情况,然后我们只需要考虑子树内两个点组合而成的情况。

  用一个数组记一下每种状态的最大深度就$over$了…

  有一个小$trick$:必须要用子树中的最优值往上更新…

//It is made by ljh2000
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
#include <bitset>
using namespace std;
typedef long long LL;
typedef long double LB;
typedef complex<double> C;
const double pi = acos(-1);
const int MAXN = 500011;
const int MAXM = 1000011;
int n,father[MAXN],ecnt,first[MAXN],to[MAXM],next[MAXM],size[MAXN],son[MAXN],deep[MAXN],ans[MAXN],Max,s[MAXN],f[10000011]/*!!!数组开小了!!!*/,inf;
char ch[MAXN];
inline void link(int x,int y){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; }
inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void dfs(int x,int fa){
size[x]=1; if(fa) s[x]=s[fa]^(1<<(ch[x]-'a'));
for(int i=first[x];i;i=next[i]) {
int v=to[i]; deep[v]=deep[x]+1;
dfs(v,x); size[x]+=size[v];
if(size[v]>size[son[x]]) son[x]=v;
}
} inline void calc(int rt,int x){
int state=s[x];
Max=max(Max,f[state]+deep[x]-2*deep[rt]);
if ((s[x]^s[rt])==0) Max=max(Max,deep[x]-deep[rt]);
for (int i=0;i<22;++i) {
state=(1<<i)^s[x];
Max=max(Max,f[state]+deep[x]-2*deep[rt]);
if ((s[x]^s[rt])==(1<<i)) Max=max(Max,deep[x]-deep[rt]);
}
for (int i=first[x];i;i=next[i])
calc(rt,to[i]);
} inline void change(int x,int type){
if(type) f[s[x]]=max(f[s[x]],deep[x]);
else f[s[x]]=inf; for(int i=first[x];i;i=next[i])
change(to[i],type);
} inline void solve(int x,bool top){
for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(v==son[x]) continue;
solve(v,1);
} if(son[x])
solve(son[x],0); Max=0; int S=s[x],nows;
Max=max(Max,f[S]-deep[x]);
for(int i=0;i<22;i++) {
nows=(1<<i)^s[x];
Max=max(Max,f[nows]-deep[x]);
} for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(v==son[x]) continue;
calc(x,v);
change(v,1);
} ans[x]=Max; if(top) {
for(int i=first[x];i;i=next[i])
change(to[i],0);
f[s[x]]=inf;
}
else f[s[x]]=max(f[s[x]],deep[x]);
} inline void upd(int x){
for(int i=first[x];i;i=next[i]) {
upd(to[i]);
ans[x]=max(ans[x],ans[to[i]]);
}
} inline void work(){
n=getint(); for(int i=2;i<=n;i++) father[i]=getint(),link(father[i],i),scanf("%c",&ch[i]);
deep[1]=0;
dfs(1,0); memset(f,-0x7f,sizeof(f)); inf=f[0];
solve(1,1);
upd(1);
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
} int main()
{
work();
return 0;
}
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

  

codeforces741D Arpa’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. [Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree

    题目链接: Codeforces741D 题目大意:给出一棵树,根为$1$,每条边有一个$a-v$的小写字母,求每个点子树中的一条最长的简单路径使得这条路径上的边上的字母重排后是一个回文串. 显然如果 ...

  8. CF741 D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    题目意思很清楚了吧,那么我们从重排回文串的性质入手. 很容易得出,只要所有字符出现的次数都为偶数,或者有且只有一个字符出现为奇数就满足要求了. 然后想到什么,Hash?大可不必,可以发现字符\(\in ...

  9. Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...

随机推荐

  1. understand EntityManager.joinTransaction()

    Join Transaction The EntityManager.joinTransaction() API allows an application managed EntityManager ...

  2. 前端 javascript 写代码方式

    javascript 和python一样可以用终端写代码 写Js代码: - html文件中编写 - 临时,浏览器的终端 console  

  3. air游戏接入小米支付sdk

    小米支付sdk要求在Application.onCreate中进行初始化 为了这个初始化搞了半天,最终搞定了.今天将更改的步骤记录下了. 1. 创建ANE.ANE的创建就不罗嗦了,这里须要注意一点,这 ...

  4. IIS 搭建过程

      Windows自带iis管理器,也就是这个 <ignore_js_op> 我们可以用它来搭建一个网站,然后在局域网内可随意访问我们的电脑.   1.首先,iis的安装.        ...

  5. DIV+CSS如何让文字垂直居中?

    在说到这个问题的时候,也许有人会问CSS中不是有vertical-align属性来设置垂直居中的吗?即使是某些浏览器不支持我只需做少许的CSS Hack技术就可以啊!所以在这里我还要啰嗦两句,CSS中 ...

  6. Jmeter(十)Linux下配置安装Jmeter及执行测试任务

    一.安装JDK7.0版本 1.先卸载服务器自带的jdk软件包 # java -version #查看服务器是否安装过 # rpm -qa |grep gcj #查看服务器安装的jdk软件包信息 # y ...

  7. GC的性能指标和内存容量配置原则

    一.GC性能指标吞吐量:应用花在非GC上的时间百分比GC负荷:与吞吐量相反,指应用花在GC上的时间百分比暂停时间:应用花在GC stop-the-world的时间GC频率反应速度:从一个对象变成垃圾到 ...

  8. CCF 201312-3 最大的矩形[比较简单]

    问题描述 试题编号: 201312-3 试题名称: 最大的矩形 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ ...

  9. django xadmin的全局配置

    在adminx.py中增加 class BaseSetting(object): enable_themes = True use_bootswatch = True class GlobalSett ...

  10. windows安装redis, php5.5

    全套安装包地址 http://download.csdn.net/detail/whellote/9572797   解压 redis-2.2.5-win32-win64, 将里面的内容拷贝到j:/r ...