#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <queue> using namespace std; /** Reference:http://www.cnblogs.com/procedure2012/archive/2012/01/29/2331460.html Thanks to: lpp学长给的模板和讲义 Pre-Knowledge:http://blog.csdn.net/c0de4fun/article/details/7879597 Tought: 没什么好说的了就是AC自动机啊,Pre-knowledge给的是数组实现的,这里是动态分配实现的。 主要就是晒模板Query函数而已。 */ struct node { node *fail; int count; node* next[26]; node() { fail = NULL; memset(next,0,sizeof(next)); count = 0; } }; const int MAX_SIZE = 1000010; const int MAX_WORD = 62; char dest[MAX_SIZE]; char word[MAX_WORD]; queue<node*> q; void AC_ins(char* word,node* root) { int len = strlen(word); node* tmp = root; for(int i = 0 ; i < len ; i++) { int k = word[i]-'a'; if( !tmp->next[k] ) tmp->next[k] = new node(); tmp = tmp->next[k]; } tmp->count++; } void AC_build(node* root) { root->fail = NULL; q.push(root); while(!q.empty()) { node* tmp = q.front(); node* p = NULL; q.pop(); for(int i = 0 ; i < 26 ; i++) { if( tmp->next[i] ) { if( tmp == root ) { tmp->next[i]->fail = root; } else { 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; } q.push(tmp->next[i]); } } } } int AC_query(node* root,char* str) { int cnt = 0; node* p = root; int len = strlen(str); for(int i = 0 ; i < len ; i++) { int ind = str[i]-'a'; while(!p->next[ind] && p != root) p = p->fail; p = p -> next[ind]; if( p == NULL ) p = root; node* tmp = p; while( tmp != root && tmp->count != -1 ) { cnt = cnt + tmp->count; //instead of cnt++? let's try; tmp->count = -1; tmp = tmp->fail; } } return cnt; } int main() { #ifndef ONLINE_JUDGE freopen("B:\\acm\\SummerVacation\\String-I\\B.in","r",stdin); freopen("B:\\acm\\SummerVacation\\String-I\\B.out","w",stdout); #endif int T,N; while( scanf("%d",&T) != EOF) { while(T--) { node* root = new node(); scanf("%d\n",&N); for(int i = 0 ; i < N ; i++) { gets(word); AC_ins(word,root); } AC_build(root); gets(dest); int ans = AC_query(root,dest); printf("%d\n",ans); } } #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }