题意:我们称一个字符串为周驿东串当且仅当重排它的字符可以组成一个回文串。
给出一个n个点的有根树,根为1,每条边上有一个从a到v的字符,求每个点的子树中所有简单路径可以组成的周驿东串中的最长长度。
n<=5e5
思路:https://www.cnblogs.com/zzqsblog/p/6146916.html
一个串为周驿东串当且仅当其中只有0/1个字符出现奇数次
将每个字母看成一个二进制位,设s[i]为根到i的边权xor和,对于固定的点x要在其子树中找到来自不同分支的a和b使得s[a]^s[b]为0或者2的次幂,且dep[a]+dep[b]-2*dep[x]最大
s[a]^s[b]的条件等价于s[a]=s[b]或者s[a]和s[b]只有1位不同
lca直接当做x算实际上的dep应该比算dep[x]大,答案会变大,需要先统计再更新
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,int>P; 11 #define N 500010 12 #define M 1000010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pi acos(-1) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 20 #define lowbit(x) x&(-x) 21 #define Rand (rand()*(1<<16)+rand()) 22 #define id(x) ((x)<=B?(x):m-n/(x)+1) 23 #define ls p<<1 24 #define rs p<<1|1 25 #define S 1<<22 26 27 const ll MOD=1e9+7,inv2=(MOD+1)/2; 28 double eps=1e-6; 29 int INF=1<<30; 30 ll inf=5e13; 31 int dx[4]={-1,1,0,0}; 32 int dy[4]={0,0,-1,1}; 33 34 char ch[10]; 35 int head[N],vet[M],nxt[M],len[M],tot; 36 int son[N],dep[N],s[N],size[N],skip; 37 int ans[N],mxdep[1<<23],now,t; 38 39 int read() 40 { 41 int v=0,f=1; 42 char c=getchar(); 43 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 44 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 45 return v*f; 46 } 47 48 void add(int a,int b,int c) 49 { 50 nxt[++tot]=head[a]; 51 vet[tot]=b; 52 len[tot]=c; 53 head[a]=tot; 54 } 55 56 void dfs1(int u,int fa) 57 { 58 size[u]=1; 59 int e=head[u]; 60 while(e) 61 { 62 int v=vet[e]; 63 if(v!=fa) 64 { 65 dep[v]=dep[u]+1; 66 s[v]=s[u]^len[e]; 67 dfs1(v,u); 68 size[u]+=size[v]; 69 if(size[v]>size[son[u]]) son[u]=v; 70 } 71 e=nxt[e]; 72 } 73 } 74 75 void clr(int u) 76 { 77 mxdep[s[u]]=-INF; 78 } 79 80 void update(int u) 81 { 82 t=max(t,mxdep[s[u]]+dep[u]-now*2); 83 rep(i,0,21) t=max(t,mxdep[s[u]^(1<<i)]+dep[u]-now*2); 84 } 85 86 void ins(int u) 87 { 88 mxdep[s[u]]=max(mxdep[s[u]],dep[u]); 89 } 90 91 void solve(int u,int fa,int op) 92 { 93 if(op==0) clr(u); 94 if(op==1) update(u); 95 if(op==2) ins(u); 96 int e=head[u]; 97 while(e) 98 { 99 int v=vet[e]; 100 if(v!=fa&&v!=skip) solve(v,u,op); 101 e=nxt[e]; 102 } 103 } 104 105 void dfs2(int u,int fa,int op) 106 { 107 int e=head[u]; 108 while(e) 109 { 110 int v=vet[e]; 111 if(v!=fa&&v!=son[u]) dfs2(v,u,0); 112 e=nxt[e]; 113 } 114 if(son[u]) 115 { 116 dfs2(son[u],u,1); 117 skip=son[u]; 118 } 119 now=dep[u]; 120 e=head[u]; 121 while(e) 122 { 123 int v=vet[e]; 124 if(v!=fa) ans[u]=max(ans[u],ans[v]); 125 e=nxt[e]; 126 } 127 e=head[u]; 128 while(e) 129 { 130 int v=vet[e]; 131 if(v!=fa&&v!=son[u]) 132 { 133 solve(v,u,1); 134 solve(v,u,2); 135 } 136 e=nxt[e]; 137 } 138 update(u); 139 ins(u); 140 ans[u]=max(ans[u],t); 141 skip=0; 142 if(!op) 143 { 144 solve(u,fa,0); 145 t=-INF; 146 } 147 } 148 149 int main() 150 { 151 //freopen("1.in","r",stdin); 152 //freopen("1.out","w",stdout); 153 154 rep(i,0,S) mxdep[i]=-INF; 155 int n=read(); 156 tot=0; 157 rep(i,2,n) 158 { 159 int x; 160 scanf("%d%s",&x,ch); 161 add(x,i,1<<(ch[0]-'a')); 162 add(i,x,1<<(ch[0]-'a')); 163 } 164 skip=t=now=0; 165 dfs1(1,0); 166 dfs2(1,0,0); 167 rep(i,1,n) printf("%d ",ans[i]); 168 return 0; 169 }