HDU2222【AC自动机(基础·模板)】
Frist AC zi dong ji(Aho-Corasick Automation) of life
#include <bits/stdc++.h> using namespace std; const int N=5e5+10; //10000个串,长度为50 struct Trie{ int num; Trie *next[27],*fail; }; Trie q[N],*root; int tol; Trie* Creat() { Trie *p; p=&q[tol++]; p->fail=NULL; p->num=0; for(int i=0;i<26;i++) p->next[i]=NULL; return p; } void Insert(char *str) { Trie *p=root; int index,len=strlen(str); for(int i=0;i<len;i++) { index=str[i]-'a'; if(p->next[index]==NULL) p->next[index]=Creat(); p=p->next[index]; } p->num++; } void Build_Ac() { queue<Trie*>que; que.push(root); while(!que.empty()) { Trie *p=que.front();que.pop(); for(int i=0;i<26;i++) { if(p->next[i]!=NULL) { if(p==root) p->next[i]->fail=root; else { Trie *temp; temp=p->fail; while(temp!=NULL) { if(temp->next[i]!=NULL) { p->next[i]->fail=temp->next[i]; break; } temp=temp->fail; } if(temp==NULL) p->next[i]->fail=root; } que.push(p->next[i]); } } } } char word[1000010]; int Query() { int ans,index,len; Trie *p=root; ans=0; len=strlen(word); for(int i=0;i<len;i++) { index=word[i]-'a'; while(p->next[index]==NULL && p!=root)//失配跳转到失败指针 p=p->fail; p=p->next[index]; if(p==NULL) //还是失配 p=root; Trie *temp=p; //p不动,temp计算后缀串 while(temp!=root && temp->num!=-1) { ans+=temp->num; temp->num=-1; temp=temp->fail; } } return ans; } int main() { char s[51]; int T; scanf("%d",&T); while(T--) { int n; tol=0; root=Creat(); scanf("%d",&n); while(n--) { scanf("%s",s); Insert(s); } Build_Ac(); scanf("%s",word); printf("%d\n",Query()); } return 0; }