存个模板。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define SZ 500005
using namespace std;
struct Trie{
int val[SZ],ch[SZ][30],tot;
int fail[SZ],lst[SZ];
void insert(char *s)
{
int p=0;
int l=strlen(s);
for(int i=0;i<l;i++)
{
int c=s[i]-'a'+1;
if(!ch[p][c]) ch[p][c]=++tot;
p=ch[p][c];
}
val[p]++;
}
void init()
{
memset(fail,0,sizeof(fail));
memset(val,0,sizeof(val));
memset(lst,0,sizeof(lst));
memset(ch,0,sizeof(ch));
tot=0;
}
queue<int> q;
void build()
{
for(int i=1;i<=26;i++)
{
int u=ch[0][i];
if(u)q.push(u);
}
while(!q.empty())
{
int r=q.front();q.pop();
for(int i=1;i<=26;i++)
{
int u=ch[r][i];
if(!u)
{
ch[r][i]=ch[fail[r]][i];
continue;
}
q.push(u);
int v=fail[r];
while(v&&!ch[v][i])v=fail[v];
fail[u]=ch[v][i];
lst[u]=val[fail[u]]?fail[u]:lst[fail[u]];
}
}
}
int dfs(int p)
{
int ans=val[p];
if(val[p]) val[p]=0;//
if(p) ans+=dfs(lst[p]);
return ans;
}
int find(char *s)
{
int l=strlen(s);
int p=0,ans=0;
for(int i=0;i<l;i++)
{
int c=s[i]-'a'+1;
while(p&&!ch[p][c])p=fail[p];
p=ch[p][c];
if(val[p]) ans+=dfs(p);
else if(lst[p])ans+=dfs(lst[p]);
}
return ans;
}
};
char s[1000005];
Trie AC;
int main()
{
int T;scanf("%d",&T);
while(T--)
{
AC.init();
int m;scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%s",s);
AC.insert(s);
}
AC.build();
scanf("%s",s);
printf("%d\n",AC.find(s));
}
return 0;
}