题意:有T组测试数据,每组测试数据给出n个]单词,然后给出一个文本,问文本里出现了多少个单词。
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct node
{
int cnt,fail,son[26];
void init()
{
cnt=fail=0;
memset(son,0,sizeof(son));
}
}T[500005];
char str[1000005];
struct AC_auto
{
int tot;
void init()
{
tot=0; T[0].init();
}
void insert(char *str)
{
int len=(int)strlen(str),h=0;
for(int i=0;i<len;i++)
{
int ind=str[i]-'a';
if(!T[h].son[ind])
{
T[h].son[ind]=++tot;
T[tot].init();
}
h=T[h].son[ind];
}
T[h].cnt++;
}
void build()
{
queue<int> que;
for(int i=0;i<26;i++) if(T[0].son[i]) que.push(T[0].son[i]);
while(que.size())
{
int top=que.front(); que.pop();
for(int i=0;i<26;i++)
{
if(T[top].son[i]==0) continue;
que.push(T[top].son[i]);
int tmp=T[top].fail;
while(tmp&&!T[tmp].son[i]) tmp=T[tmp].fail;
T[T[top].son[i]].fail=T[tmp].son[i];
}
}
}
int query(char *str)
{
int len=(int)strlen(str),h=0,res=0;
for(int i=0;i<len;i++)
{
int ind=str[i]-'a';
while(h&&!T[h].son[ind]) h=T[h].fail;
h=T[h].son[ind];
int tmp=h;
while(tmp&&T[tmp].cnt!=-1)
{
res+=T[tmp].cnt;
T[tmp].cnt=-1;
tmp=T[tmp].fail;
}
}
return res;
}
}AC;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
AC.init();
while(n--)
{
scanf("%s",str);
AC.insert(str);
}
AC.build();
scanf("%s",str);
printf("%d\n",AC.query(str));
}
return 0;
}