做法是从每个叶子节点为根DFS,建广义SAM统计答案
全部WA了,不知道哪里写锅了,最近眼睛有点瞎,怎么都看不出来哪有锅
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=4e6+5;
int n,k,c,u,v,tot=1;
long long ans;
int head[N],deg[N],x[N];
struct edge{
int v,next;
}e[N];
struct node{
int len,fa;
int ch[10];
}t[N];
inline void add(int u,int v)
{
e[++k]=(edge){v,head[u]};
head[u]=k,++deg[v];
}
inline int insert(int c,int p)
{
int np=++tot;
t[np].len=t[p].len+1;
while(p&&!t[p].ch[c]) t[p].ch[c]=np,p=t[p].fa;
if(!p) t[np].fa=1;
else
{
int q=t[p].ch[c];
if(t[q].len==t[p].len+1) t[np].fa=q;
else
{
int nq=++tot;
t[nq]=t[q];
t[nq].len=t[p].len+1;
t[q].fa=t[np].fa=nq;
while(p&&t[p].ch[c]==q) t[p].ch[c]==nq,p=t[p].fa;
}
}
return np;
}
void DFS(int u,int fa,int p)
{
p=insert(x[u],p);
for(register int i=head[u];i;i=e[i].next)
if(e[i].v!=fa) DFS(e[i].v,u,p);
}
int main(void)
{
scanf("%d%d",&n,&c);
for(register int i=1;i<=n;++i)
scanf("%d",&x[i]);
for(register int i=1;i<n;++i)
{
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
for(register int i=1;i<=n;++i)
if(deg[i]==1) DFS(i,0,1);
for(register int i=2;i<=tot;++i)
ans+=t[i].len-t[t[i].fa].len;
printf("%lld\n",ans);
return 0;
}