#include <cstdio>
#include <cstring>
using namespace std;
const int num_char=26;
struct TrieNode
{
TrieNode *branch[num_char];
TrieNode *fail;
int count;//if this is the last node of the word
TrieNode()
{
fail=NULL;
count=0;
memset(branch,NULL,sizeof(branch));
}
} *q[500001];
int qhead,qtail;
char src[1000005];
char input[55];
void insert(const char *src,TrieNode *root)
{
TrieNode *hp=root;
while(*src!=0)
{
if(hp->branch[*src-'a']==NULL)hp->branch[*src-'a']=new TrieNode();
hp=hp->branch[*src-'a'];
src++;
}
hp->count++; //+1 stands for it's the end of a word.
}
void build_fail(TrieNode *root)
{
int i;
root->fail=NULL;
q[qhead++]=root;
while(qhead!=qtail)
{
TrieNode *temp=q[qtail++];
TrieNode *p=NULL;
for(i=0; i<26; i++)
{
if(temp->branch[i]!=NULL)
{
if(temp==root)temp->branch[i]->fail=root;
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->branch[i]!=NULL)
{
temp->branch[i]->fail=p->branch[i];
break;
}
p=p->fail;
}
if(p==NULL)temp->branch[i]->fail=root;
}
q[qhead++]=temp->branch[i];
}
}
}
}
int query(TrieNode *root)
{
int i=0,cnt=0,index;
TrieNode *p=root;
while(src[i]!=0)
{
index=src[i]-'a';
while(p->branch[index]==NULL&& p!=root)p=p->fail;
p=p->branch[index];
p=(p==NULL)?root:p;
TrieNode *temp=p;
while(temp!=root&&temp->count!=-1)
{
cnt+=temp->count;
temp->count=-1;
temp=temp->fail;
}
i++;
}
return cnt;
}
int main()
{
int n;
int t;
scanf("%d",&t);
while(t--)
{
TrieNode *root=new TrieNode();
qtail=qhead=0;
scanf("%d",&n);
for(int i=0; i<n; ++i)
{
scanf("%s",input);
insert(input,root);
}
build_fail(root);
// printf("input target:\n");
scanf("%s",src);
printf("%d\n",query(root));
}
return 0;
}
转载于:https://www.cnblogs.com/MicZ/archive/2012/10/24/2785360.html