http://blog.csdn.net/niushuai666/article/details/7002823
#include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node{ int count; node *next[26],*fail; void Node(){ count = 0;fail = NULL; memset(next,NULL,sizeof(next)); } }arr[300005],*que[500005]; char str[1000006]; int cnt = 0; void insert(char *str){ node *p = &arr[0]; while( *str ){ int k = *str++ - 'a'; if( !p->next[k] ){ arr[++cnt].Node(); p->next[k] = &arr[cnt]; } p = p->next[k]; } p->count++; } void build_AC(){ node *root = &arr[0],*tmp,*p; int head = 0,tail = 0; for(int i = 0; i < 26; i++){ if(!root->next[i])continue; root->next[i]->fail = root; que[head++] = root->next[i]; } while( head != tail){ tmp = que[tail++]; for(int i = 0; i < 26 ; i++){ if( tmp->next[i] ){ p = tmp->fail; while( p ){ if( p->next[i] ){ tmp->next[i]->fail = p->next[i]; break; } p = p->fail; } if(!p)tmp->next[i]->fail = root; que[head++] = tmp->next[i]; } } } } int query(char *str){ node *root = &arr[0],*p = &arr[0]; int ans= 0; while( *str ){ int k = *str++ - 'a'; while( !p->next[k] && p != root) p = p->fail; p = p->next[k]; p = p ? p : root; node *tmp = p; while( tmp != root && tmp->count != -1){ ans += tmp->count; tmp->count = -1; tmp = tmp->fail; } } return ans; } int main(){ // freopen("in.txt","r",stdin); int t,n; char ch[60]; scanf("%d",&t); while( t-- ){ scanf("%d",&n); arr[cnt = 0].Node(); while( n-- ){ scanf("%s",ch); insert(ch); } build_AC(); scanf("%s",str); printf("%d ",query(str)); } return 0; }