#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 100005
#define maxl 200005
#define maxm 4000005
using namespace std; typedef long long ll;
int n,c,cnt,tot,root,last,fa[maxm],du[maxn],dist[maxm],son[maxl],prep[maxl],now[maxn],v[maxn];
ll ans;
void add(int x,int y){
cnt++,prep[cnt]=now[x],now[x]=cnt,son[cnt]=y;
}
struct Tsegment{
int son[maxm][];
void prepare(){tot=last=root=;memset(dist,,sizeof(dist));}
int newnode(int x){dist[++tot]=x; return tot;}
int add(int x,int p){
int q=son[p][x];
if (q==){
int np=newnode(dist[p]+); last=np;
for (;p&&!son[p][x];p=fa[p]) son[p][x]=np;
if (p==) fa[np]=root;
else{
q=son[p][x];
if (dist[p]+==dist[q]) fa[np]=q;
else{
int nq=newnode(dist[p]+);
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for (;p&&son[p][x]==q;p=fa[p]) son[p][x]=nq;
}
}
}else{
if (dist[p]+==dist[q]) last=q;
else{
int nq=newnode(dist[p]+); last=nq;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q],fa[q]=nq;
for (;p&&son[p][x]==q;p=fa[p]) son[p][x]=nq;
}
}
return last;
}
}SAM;
void dfs(int x,int pa,int goal){
int p=SAM.add(v[x],goal);
for (int i=now[x],so=son[i];i;i=prep[i],so=son[i]){
if (so==pa) continue;
dfs(so,x,p);
}
}
int main(){
scanf("%d%d",&n,&c);
memset(du,,sizeof(du));
cnt=tot=ans=,memset(now,,sizeof(now));
for (int i=;i<=n;i++) scanf("%d",&v[i]);
for (int u,v,i=;i<n;i++) scanf("%d%d",&u,&v),add(u,v),add(v,u),du[u]++,du[v]++;
SAM.prepare();
for (int i=;i<=n;i++){
if (du[i]>) continue;
dfs(i,,root);
}
ans=;
dist[root]=;
for (int i=;i<=tot;i++) ans+=(dist[i]-dist[fa[i]]);
printf("%lld\n",ans);
return ;
}
做法:广义后缀自动机模板题。
dfs+后缀自动机。