|
#include <iostream> using namespace std;
const int MAXN=50*10005; const int MAXL=1005; const int K=26;
struct Node { Node *next[K], *fail; int flag, id; void Init(int index) { id=index; flag=0; fail=NULL; for(int i=0; i<K; i++)next[i]=NULL; } }* Q[MAXN/2], *root, T[MAXN];// Q for queue, root&T for tree;
int index=0; Node * newNode() { T[index].Init(index); return &T[index++]; }
int tokind(char k){return k-'a';}
void insert(char *str) { if(root==NULL) root=newNode();
Node *now=root; for(int i=0; str[i]; i++) { int kind=tokind(str[i]); if(now->next[kind]==NULL) now->next[kind]=newNode(); now=now->next[kind]; } now->flag++; }
void buildAC() { int head=0, tail=0; root->fail=NULL;
Q[tail++]=root; while(head<tail) { Node *now=Q[head++]; for(int i=0; i<K; i++) { if(now->next[i]!=NULL) { if(now==root)now->next[i]->fail=root; else { Node *p=now->fail; while(p->next[i]==NULL&&p!=root)p=p->fail; p=p->next[i]; now->next[i]->fail=(p==NULL)?root:p; } Q[tail++]=now->next[i]; } } } }
int query(char *str) { int res=0; Node *p=root; for(int i=0; str[i]; i++) { int kind=tokind(str[i]); while(p->next[kind]==NULL&&p!=root)p=p->fail; p=p->next[kind]; p=(p==NULL)?root:p; Node *now=p; while(now!=root&&now->flag!=-1) { res+=now->flag; now->flag=-1; now=now->fail; } } return res; }
int main() { //freopen ("in.txt", "r", stdin); int T; scanf("%d", &T); while(T--) { int n; root=NULL; scanf("%d",&n);getchar(); while(n--) { char str[55]; scanf("%s",str); insert(str); } buildAC(); char ch[1000005]; scanf("%s",ch); printf("%d\n",query(ch)); } return 0; }
|