rt,是被卡常了还是写假了/kk
#include<iostream>
using namespace std;
const int N=1e6+5,M=(1<<22)+10;
struct edge{
int v,c,nxt;
};
edge e[N*2];
int n,h[N],d[N],siz[N],p[N],w[N],f[N],l[N],r[N],inv[N],tot,cnt;
int t[M];
int dp[N];
char ch;
void add(int u,int v,int c){
e[++tot].v=v;
e[tot].c=c;
e[tot].nxt=h[u];
h[u]=tot;
}
void dfs(int u,int fa){
siz[u]=1;
l[u]=++cnt;
d[u]=d[fa]+1;
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v,c=e[i].c;
siz[u]+=siz[v];
p[v]=p[u]^(1<<c);
dfs(v,u);
if(siz[v]>siz[w[u]]) w[u]=v;
}
r[u]=cnt;
}
void update(int u,int fa){
t[p[u]]=max(t[p[u]],d[u]);
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;
update(v,u);
}
}
void del(int u,int fa){
t[p[u]]=0;
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;
del(v,u);
}
}
void solve(int u,int fa){
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==w[u]) continue;
solve(v,u);
dp[u]=max(dp[u],dp[v]);
del(v,u);
}
if(w[u]) solve(w[u],u);
for(int i=0;i<22;i++){
if(t[p[u]^(1<<i)]){
dp[u]=max(dp[u],t[p[u]^(1<<i)]-d[u]);
}
}
if(t[p[u]]) dp[u]=max(dp[u],t[p[u]]-d[u]);
dp[u]=max(dp[u],dp[w[u]]);
t[p[u]]=max(t[p[u]],d[u]);
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==w[u]) continue;
for(int j=l[v];j<=r[v];j++){
int c=inv[j];
for(int k=0;k<22;k++){
if(t[p[c]^(1<<k)]) dp[u]=max(dp[u],t[p[c]^(1<<k)]+d[c]-2*d[u]);
}
if(t[p[c]]) dp[u]=max(dp[u],t[p[c]]+d[c]-2*d[u]);
}
update(v,u);
}
}
int main(){
ios::sync_with_stdio(0);
cin>>n;
for(int i=2,x;i<=n;i++){
cin>>x>>ch;
add(x,i,ch-'a');
}
dfs(1,0);
for(int i=1;i<=n;i++) inv[l[i]]=i;
solve(1,0);
for(int i=1;i<=n;i++){
cout<<dp[i]<<" ";
}
return 0;
}