广义后缀自动机其实就是简单的把所有的串都插到了一起而已。。。。
每添加进一个新的字符其实影响到的字串也就是能新增加的字串就是fail链上的,每一次新加入一个字符向上更新影响就好了
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 200021
using namespace std;
int n,last=1,m,tot=1,rt=1,son[maxn][26],len[maxn];
int fail[maxn],bl[maxn],now,sum[maxn];
char s[maxn];
void insert(int c){
int p=last,np=++tot,q,nq;
len[np]=len[p]+1;last=np;
while(p&&!son[p][c])son[p][c]=np,p=fail[p];
if(!p)fail[np]=rt;
else{
q=son[p][c];
if(len[q]==len[p]+1)fail[np]=q;
else{
nq=++tot;
len[nq]=len[p]+1,sum[nq]=sum[q];
fail[nq]=fail[q],bl[nq]=bl[q];
memcpy(son[nq],son[q],sizeof(son[q]));
fail[np]=fail[q]=nq;
while(p&&son[p][c]==q)son[p][c]=nq,p=fail[p];
}
}
while(np&&bl[np]!=now){
sum[np]++;
bl[np]=now;
np=fail[np];
}
}
int main(){
scanf("%d%d",&n,&m);
for(int len,i=1;i<=n;i++){
scanf("%s",s);len=strlen(s);
now=i,last=rt;
for(int j=0;j<len;j++)
insert(s[j]-'a');
}
int x,len;
while(m--){
scanf("%s",s);len=strlen(s);
x=1;
for(int i=0;i<len;i++)x=son[x][s[i]-'a'];
printf("%d\n",sum[x]);
}
return 0;
}