-
题解:
- 如果树上某个路径串的端点不是叶子,那么一定是另一个串的子串;
- 这样只对叶子$dfs$把$20*20$个串插入广义$SAM$就是统计本质不同的串的个数的模板了;
- 我不太会分析广义$SAM$的空间,但是我知道似乎完全图是有$n-1$条欧拉回路的,所以长度不会超过$2n*(20-1)$,需要卡一卡;
- 可能后面会补广义的坑吧。。。。
-
1 #include<bits/stdc++.h> 2 #define rg register 3 #define il inline 4 #define ll long long 5 using namespace std; 6 const int N=100010,M=40; 7 int n,m,sz,mx[N*M],pa[N*M],s[N],len,col[N],ch[N*M][10],d[N],cnt,a[N],w[N],st[N*M],o,hd[N]; 8 ll val[N*M]; 9 struct Edge{int v,nt;}E[N<<1]; 10 il char gc(){ 11 static char*p1,*p2,S[1000000]; 12 if(p1==p2)p2=(p1=S)+fread(S,1,1000000,stdin); 13 return(p1==p2)?EOF:*p1++; 14 } 15 il int rd(){ 16 int x=0;char c=gc(); 17 while(c<'0'||c>'9')c=gc(); 18 while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc(); 19 return x; 20 } 21 il void adde(int u,int v){ 22 E[o]=(Edge){v,hd[u]};hd[u]=o++;d[u]++; 23 E[o]=(Edge){u,hd[v]};hd[v]=o++;d[v]++; 24 } 25 il void ins(){ 26 /* 27 for(int i=1;i<=len;i++)printf("%d ",s[i]); 28 puts(""); 29 */ 30 int lst=1,np,nq,p,q,x; 31 for(rg int i=1;i<=len;i++){ 32 x=s[i]; 33 p=lst; mx[lst=np=++sz]=mx[p]+1; 34 while(p&&!ch[p][x])ch[p][x]=np,p=pa[p]; 35 if(!p){pa[np]=1;continue;} 36 q=ch[p][x]; 37 if(mx[q]==mx[p]+1)pa[np]=q; 38 else { 39 mx[nq=++sz]=mx[p]+1; 40 memcpy(ch[nq],ch[q],sizeof(ch[q])); 41 pa[nq]=pa[q];pa[q]=pa[np]=nq; 42 while(p&&ch[p][x]==q)ch[p][x]=nq,p=pa[p]; 43 } 44 } 45 } 46 il void dfs(int u,int fa){ 47 for(rg int i=hd[u];i;i=E[i].nt){ 48 int v=E[i].v; 49 if(v==fa)continue; 50 s[++len]=col[v]; 51 dfs(v,u); 52 } 53 if(d[u]==1&&fa)ins(); 54 len--; 55 } 56 int main(){ 57 #ifndef ONLINE_JUDGE 58 freopen("bzoj3926.in","r",stdin); 59 freopen("bzoj3926.out","w",stdout); 60 #endif 61 n=rd();m=rd(); 62 for(rg int i=1;i<=n;i++)col[i]=rd(); 63 for(rg int i=o=1;i<n;i++)adde(rd(),rd()); 64 sz=1; 65 for(rg int i=1;i<=n;i++)if(d[i]==1)a[++cnt]=i; 66 for(int i=1;i<=cnt;i++){ 67 s[len=1]=col[a[i]]; 68 dfs(a[i],0); 69 } 70 for(rg int i=1;i<=sz;i++)w[mx[i]]++; 71 for(rg int i=1;i<=n;i++)w[i]+=w[i-1]; 72 for(rg int i=sz;i;i--)st[w[mx[i]]--]=i; 73 for(rg int i=sz,u;i;i--){ 74 val[u=st[i]]=1; 75 for(rg int j=0;j<m;j++){ 76 val[u]+=val[ch[u][j]]; 77 } 78 } 79 --val[1]; 80 printf("%lld\n",val[1]); 81 return 0; 82 }