代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
const int N=500000+5;
struct node
{
int data;
int count;
int fail;
int next[26];
}tree[N];
void init(node &a,int data)
{
a.data=data;
a.count=0;
a.fail=0;
for (int i=0;i<26;i++)
a.next[i]=-1;
}
int k=1;
void Insert(char s[])
{
int p=0;
for(int i=0;s[i];i++)
{
int data=s[i]-'a';
if(tree[p].next[data]==-1)
{
init(tree[k],data);
tree[p].next[data]=k;
k++;
}
p=tree[p].next[data];
}
tree[p].count++;
}
queue<node> q;
void AC_automation()
{
q.push(tree[0]);
while(!q.empty())
{
node k = q.front();
q.pop();
for(int j=0;j<26;j++)
{
if(k.next[j]!=-1)
{
if(k.data==-1) tree[k.next[j]].fail=0;
else
{
int t=k.fail;
while(t!=0&&tree[t].next[j]==-1)
t=tree[t].fail;
tree[k.next[j]].fail=max(tree[t].next[j],0 );
}
q.push(tree[k.next[j]]);
}
}
}
}
int get_ans(char s[])
{
int k=0,ans=0;
for(int i=0;s[i];i++)
{
int t=s[i]-'a';
while(tree[k].next[t]==-1&&k)k=tree[k].fail;
k = tree[k].next[t];
if(k==-1)
{
k=0;
continue;
}
int j=k;
while(tree[j].count)
{
ans+=tree[j].count;
tree[j].count=0;
j=tree[j].fail;
}
ans+=tree[tree[j].fail].count;
tree[tree[j].fail].count=0;
}
return ans;
}
char tar[2*N];
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init(tree[0],-1);
char a[55];
while(n--)
{
scanf("%s",a);
Insert(a);
}
AC_automation();
scanf("%s",tar);
printf("%d\n",get_ans(tar));
}
return 0;
}