AC自動機的算法參考:http://www.cppblog.com/mythit/archive/2009/04/21/80633.html
#include <stdio.h>
#include <string.h>
int tot;
char str[1000005];
int t;
//int time[100];
struct trie {
trie *fail;
trie *next[26];
int num;
trie() {
for(int i=0; i<26; i++)
next[i]=NULL;
fail=NULL;
num=0;
}
}*queue[500001];
trie *root;
void build() { //建立字典樹
int len=strlen(str);
trie *p=root;
for(int i=0; i<len; i++) {
int id=str[i]-'a';
if(p->next[id]==NULL)
p->next[id]=new trie();
p=p->next[id];
}
p->num++;
}
void build_fail() { //建立失敗指針,用bfs搜一遍所有的點
int i;
trie *u,*v;
int fr,ed;
fr=ed=0;
root->fail=NULL;
queue[ed++]=root;
while(fr<ed)
{
u=queue[fr++];
v=NULL;
for(i=0; i<26; i++)
{
if(u->next[i]!=NULL)
{
if(u==root)
u->next[i]->fail=root;
else
{
v=u->fail;
while(v!=NULL)
{
if(v->next[i]!=NULL)
{
u->next[i]->fail=v->next[i];
break;
}
v=v->fail;
}
if(v==NULL) //如果剛進入就是root,也要賦值
u->next[i]->fail=root;
}
queue[ed++]=u->next[i];
}
}
}
}
int search() { //查找字符串
int i=0;
trie *p=root;
int all=0;
while(str[i]) {
int id=str[i]-'a';
while(p->next[id]==NULL&&p!=root)
p=p->fail;
p=p->next[id];
p=(p==NULL)?root:p;
trie *q=p;
while(q!=root&&q->num!=-1) {
all+=q->num;
q->num=-1; //標記已經找過的單詞
q=q->fail;
}
i++;
}
return all;
}
int main() {
int n;
int i;
int tt;
scanf("%d",&tt);
while(tt--) {
scanf("%d",&n);
tot=0;
root=new trie();
for(i=0; i<n; i++) {
scanf("%s",str);
build();
}
build_fail();
scanf("%s",str);
printf("%d\n",search());
}
return 0;
}