AC 自动机的入门题。
看大白 和 这里 学习的AC自动机
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int max_next = 26;
struct trie
{
struct trie *fail;
struct trie *next[max_next];
int count;
};
trie *Q[500005];
int head,tail;
char str[1000005];
void insert(trie *root,char *word)
{
trie *p=root;
int i=0;
while(word[i]!='\0')
{
if(p->next[word[i]-'a']==NULL)
{
trie *temp = new trie;
for(int j=0;j<max_next;j++)temp->next[j]=NULL;
temp->count=0;
temp->fail=NULL;
p->next[word[i]-'a']=temp;
}
p=p->next[word[i]-'a'];
i++;
}
p->count++;
}
void acbuild(trie *root)
{
root->fail=NULL;
head=tail=0;
Q[tail++]=root;
while(head<tail)
{
trie *temp=Q[head++];
trie *p=NULL;
for(int i=0;i<max_next;i++)
{
if(temp->next[i]!=NULL)
{
if(temp==root)temp->next[i]->fail=root;
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)temp->next[i]->fail=root;
}
Q[tail++]=temp->next[i];
}
}
}
}
int query(trie *root)
{
int i=0;
int cnt=0;
int len=strlen(str);
trie *p=root;
int index;
while(str[i])
{
int index = str[i]-'a';
while(p->next[index]==NULL && p!=root)
p=p->fail;
p=p->next[index];
if(p==NULL)p=root;
trie *temp=p;
while(temp!=NULL)
{
cnt+=temp->count;
temp->count=0;
temp=temp->fail;
}
i++;
}
return cnt;
}
void del(trie *root)
{
for(int i=0;i<max_next;i++)
if(root->next[i])del(root->next[i]);
free(root);
}
char word[55];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
trie *root = new trie;
root->count=0;
for(int i=0;i<max_next;i++)root->next[i]=NULL;
root->fail=NULL;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",word);
insert(root,word);
}
acbuild(root);
scanf("%s",str);
printf("%d\n",query(root));
del(root);
}
return 0;
}