Orz Kuangbin和昀牛--
#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 maxn=500000+10; struct AC_machine { int next[maxn][26],fail[maxn],end[maxn]; int root,L; inline int newnode() { rep(i,0,26) next[L][i]=-1; end[L++]=0; return L-1; } inline void init() { L=0; root=newnode(); } inline void insert(char str[]) { 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]++; } inline void build_AC()//BFS构建AC自动机的过程; { queue<int>q; fail[root]=root;//根节点的失败指针指向自己; rep(i,0,26) { 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,26) { 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 int match(char str[]) { int len=strlen(str); int now=root; int res=0; rep(i,0,len) { now=next[now][str[i]-'a']; int temp=now; while(temp!=root) { res+=end[temp]; end[temp]=0; temp=fail[temp]; } } return res; } 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 < 26;j++) printf("%2d",next[i][j]); printf("]\n"); } } }AC; char str[maxn<<1]; int test,n; int main() { scanf("%d",&test); while(test--) { scanf("%d",&n); AC.init(); rep(i,0,n) { scanf("%s",str); AC.insert(str); } //AC.debug(); AC.build_AC(); scanf("%s",str); printf("%d\n",AC.match(str)); } //A; return 0; } |
* This source code was highlighted by YcdoiT. ( style: Emacs )