套dsu on tree的套路
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define maxx 500005
#define INF 0x7f7f7f7f
using namespace std;
int n;
int head[maxx],to[maxx],_next[maxx];
int edge;
inline void addEdge(int x,int y)
{
to[++edge]=y,_next[edge]=head[x],head[x]=edge;
}
int deep[maxx];
int _size[maxx];
int son[maxx];
int D[maxx];
void dfs1(int u,int fa)
{
_size[u]=1;
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
deep[v]=deep[u]+1;
D[v]^=D[u];
dfs1(v,u);
_size[u]+=_size[v];
if(_size[son[u]]<_size[v])son[u]=v;
}
}
int l[maxx],r[maxx],_index;
int a[maxx];
void dfs2(int u,int fa)
{
l[u]=++_index;
a[_index]=u;
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
dfs2(v,u);
}
r[u]=_index;
}
int c[1<<22];
void del(int u)
{
for(int i=l[u];i<=r[u];i++)c[D[a[i]]]=0;
}
int ans[maxx];
int dfs(int u)
{
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v==son[u])continue;
dfs(v);
del(v);
ans[u]=max(ans[u],ans[v]);
}
if(son[u])
{
dfs(son[u]);
ans[u]=max(ans[u],ans[son[u]]);
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v!=son[u])
{
for(int i=l[v];i<=r[v];i++)
{
if(c[D[a[i]]])ans[u]=max(ans[u],deep[a[i]]+c[D[a[i]]]-2*deep[u]);
for(int j=0;j<22;j++)
if(c[(1<<j)^D[a[i]]])
ans[u]=max(ans[u],deep[a[i]]+c[(1<<j)^D[a[i]]]-2*deep[u]);
}
for(int i=l[v];i<=r[v];i++)c[D[a[i]]]=max(c[D[a[i]]],deep[a[i]]);
}
}
}
if(c[D[u]])ans[u]=max(ans[u],c[D[u]]-deep[u]);
for(int i=0;i<22;i++)
if(c[(1<<i)^D[u]])ans[u]=max(ans[u],c[(1<<i)^D[u]]-deep[u]);
c[D[u]]=max(c[D[u]],deep[u]);
}
int main()
{
cin>>n;
char s[5];
int x;
for(int i=2;i<=n;i++)
{
scanf("%d%s",&x,s);
addEdge(x,i);
D[i]=1<<(s[0]-'a');
}
//deep[1]=1;
dfs1(1,0);
dfs2(1,0);
dfs(1);
for(int i=1;i<n;i++)printf("%d ",ans[i]);
printf("%d\n",ans[n]);
return 0;
}