BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串
Posted 鲸头鹳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串相关的知识,希望对你有一定的参考价值。
https://www.lydsy.com/JudgeOnline/problem.php?id=3926
广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比较方便)。
后缀自动机可以说是一种存子串的缩小点数的trie树,广义后缀自动机就是更改了一下塞点的方式让它可以塞多个子串。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define LL long long 9 const int maxn=100100; 10 int n,c; 11 int val[maxn]={}; 12 struct nod{ 13 int y,next; 14 }e[maxn*2];int head[maxn]={},tot=0; 15 int a[maxn]={}; 16 struct node{ 17 int sig[15],f,len; 18 }t[maxn*40];int tly=1; 19 inline void init(int x,int y){ e[++tot].y=y; e[tot].next=head[x]; head[x]=tot; } 20 int addit(int k,int z){ 21 int x=++tly; t[x].len=t[k].len+1; 22 for(;k&&!t[k].sig[z];k=t[k].f) 23 t[k].sig[z]=x; 24 if(k==0)t[x].f=1; 25 else{ 26 int y=t[k].sig[z]; 27 if(t[y].len==t[k].len+1)t[x].f=y; 28 else{ 29 int p=++tly; t[p]=t[y]; t[p].len=t[k].len+1; 30 t[x].f=t[y].f=p; 31 for(;k&&t[k].sig[z]==y;k=t[k].f) 32 t[k].sig[z]=p; 33 } 34 } 35 return x; 36 } 37 void dfs(int x,int fa,int k){ 38 int nt=addit(k,val[x]); 39 for(int i=head[x];i;i=e[i].next) 40 if(fa!=e[i].y)dfs(e[i].y,x,nt); 41 } 42 int main(){ 43 memset(t,0,sizeof(t)); 44 int x,y; 45 scanf("%d%d",&n,&c); 46 for(int i=1;i<=n;++i)scanf("%d",&val[i]); 47 for(int i=1;i<n;++i){ 48 scanf("%d%d",&x,&y); 49 init(x,y);init(y,x); a[x]++;a[y]++; 50 } 51 for(int i=1;i<=n;++i)if(a[i]==1)dfs(i,0,1); 52 LL ans=0; 53 for(int i=1;i<=tly;++i)ans+=(LL)(t[i].len-t[t[i].f].len); 54 printf("%lld\n",ans); 55 return 0; 56 }
以上是关于BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串的主要内容,如果未能解决你的问题,请参考以下文章