很裸的一个模板题目。
/**************************** * author:crazy_石头 * date:2014/01/11 * algorithm:Aho-Corasick自动机 * Pro:HDU3065-病毒持续侵袭中 *****************************/ #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> using namespace std; #define INF 1<<29 #define eps 1e-8 #define A system("pause") #define rep(i,h,n) for(int i=(h);i<(n);i++) #define ms(a,b) memset((a),(b),sizeof(a)) const int maxm=1000+10; const int maxn=50000+10; const int sigma_size=128; const int maxlen=2000000+5; char str[maxlen]; char ch[maxn][sigma_size]; int n; struct AC_machine { int next[maxn][sigma_size],fail[maxn],end[maxn],hash[maxm];//end数组记录每个串的id; int root,L; inline int newnode() { for(int i=0;i<sigma_size;i++) next[L][i]=-1; end[L++]=-1; return L-1; } inline void init() { L=0; root=newnode(); } inline void insert(char str[],int id) { int len=strlen(str); int now=root; rep(i,0,len) { if(next[now][str[i]-'A']==-1) next[now][str[i]-'A']=newnode(); now=next[now][str[i]-'A']; } end[now]=id; } inline void build_AC() { queue<int>q; fail[root]=root; rep(i,0,sigma_size) { if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; q.push(next[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); rep(i,0,sigma_size) { if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; q.push(next[now][i]); } } } } inline void solve(char str[],int n) { rep(i,0,n) hash[i]=0; int len=strlen(str); int now=root; rep(i,0,len) { now=next[now][str[i]-'A']; int temp=now; while(temp!=root) { if(end[temp]!=-1) hash[end[temp]]++; temp=fail[temp]; } } rep(i,0,n) if(hash[i]>0) printf("%s: %d\n",ch[i],hash[i]); } inline void debug() { for(int i=0;i<L;i++) { printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]); for(int j=0;j<sigma_size;j++) printf("%2d",next[i][j]); printf("]\n"); } } }AC; int main() { while(~scanf("%d",&n)) { AC.init(); rep(i,0,n) { scanf("%s",ch[i]); AC.insert(ch[i],i); } AC.build_AC(); //AC.debug(); scanf("%s",str); AC.solve(str,n); } return 0; }