ac自动机,模板题
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 500000+5;
const int LEN = 50+5;
const int SIGMA = 26;
char a[LEN],b[MAXN*2];
int trie[MAXN][SIGMA],q[MAXN],f[MAXN],val[MAXN],vis[MAXN];
int T,n,sz,ans;
inline int idx(char c){return c-'a';}
void insert(char*s)
{
int u=0,len=strlen(s);
for(int i=0;i<len;i++)
{
int c=idx(s[i]);
if(!trie[u][c])
{
sz++;
trie[u][c]=sz;
memset(trie[sz],0,sizeof(trie[sz]));
val[sz]=0;/*useless*/
}
u=trie[u][c];
}
val[u]++;
}
void getfail()
{
int s=0,t=0,u;
f[0]=0;
for(int c=0;c<SIGMA;c++)
{
u=trie[0][c];
if(u){f[u]=0;q[t++]=u;}
}
while(s<t)
{
u=q[s++];
for(int c=0;c<SIGMA;c++)
{
if(!trie[u][c])trie[u][c]=trie[f[u]][c];
else
{
f[trie[u][c]]=trie[f[u]][c];
q[t++]=trie[u][c];
}
}
}
}
void find(char*s)
{
int j=0,len=strlen(s);
for(int i=0;i<len;i++)
{
vis[j]=1;
int c=idx(s[i]);
while(j && !trie[j][c])j=f[j];
j=trie[j][c];
if(!vis[j])
{
for(int k=j; k ;k=f[k])
{
ans+=val[k];
val[k]=0;
}
}
}
printf("%d\n",ans);
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(f,0,sizeof(f));
memset(q,0,sizeof(q));
memset(val,0,sizeof(val));
memset(vis,0,sizeof(vis));
memset(trie[0],0,sizeof(trie[0]));
sz=ans=0;
scanf("%d",&n);
while(n--)
{
scanf("%s",a);
insert(a);
}
getfail();
scanf("%s",b);
find(b);
}
return 0;
}