#include <iostream>
#include <stdio.h>#include <queue>using namespace std;const int maxn=(int)1e6+10;const int maxm=(int)5e5+10;struct trie{ int nxt[maxm][26],fail[maxm],ed[maxm]; int rt,l; int newnod(){ for(int i=0;i<26;i++)nxt[l][i]=-1; ed[l++]=0; return l-1; } void init(){ l=0;rt=newnod(); } void inset(char s[]){ int now=rt; for(int i=0;s[i];i++){ if(nxt[now][s[i]-'a']==-1)nxt[now][s[i]-'a']=newnod(); now=nxt[now][s[i]-'a']; } ed[now]++; } void build(){ static queue<int>q;fail[rt]=rt;for(int i=0;i<26;i++)
if(nxt[rt][i]==-1)nxt[rt][i]=rt; else{ fail[nxt[rt][i]]=rt;q.push(nxt[rt][i]); } while(!q.empty()){ int now=q.front(); q.pop(); for(int i=0;i<26;i++){ if(nxt[now][i]==-1) nxt[now][i]=nxt[fail[now]][i]; //如果当前单词的下一个字母结点为空,当前单词的该字母结点指 //向fail结点的对应字母结点 else{ //如果当前单词的下一个字母结点不为空,当前单词的该字母结点的fail结点 //指向fail结点的对应字母结点 fail[nxt[now][i]]=nxt[fail[now]][i]; q.push(nxt[now][i]); } } } } //fail[i]即i结点所在单词以i结点为结尾和其它单词中以i结点代表字母为结尾的公共最长后前缀的结点 int query(char s[]){ int now=rt,res=0; for(int i=0;s[i];i++){ now=nxt[now][s[i]-'a']; //新start=上一个start的s[i]字母结点的nxt指向结点,单词存在就指向单词下一个字母, //不存在指向别的单词的该字母,就指向fail[st]的nxt指向结点 // int tmp=now; printf("s[%d]: %c tmp :%d now:%d\n",i,s[i],tmp,now); while(tmp!=rt){if(ed[tmp]==1)printf("--%d\n",tmp);
res+=ed[tmp];ed[tmp]=0;tmp=fail[tmp]; printf("tmp:%d\n",tmp); } } return res; } void debug(){ printf("id = %3d fail = %3d ed= %3d chi = [",0,0,0); for(int j=0;j<26;j++)printf("%2c",'a'+j);printf("\n"); for(int i=0;i<l;i++){ printf("id = %3d fail = %3d ed= %3d chi = [",i,fail[i],ed[i]); for(int j=0;j<26;j++)printf("%2d",nxt[i][j]);printf("\n"); } }};
char s[maxn];trie ac;void dfs(int st,string tmp=""){
if(ac.ed[st]!=0) cout<<tmp<<endl; for(int i=0;i<26;i++){ if(ac.nxt[st][i]!=-1) dfs(ac.nxt[st][i],tmp+(char)('a'+i)); }}void dfs1(int st,string tmp=""){ if(ac.ed[st]!=0) cout<<tmp<<endl; for(int i=0;i<26;i++){ if(ac.nxt[st][i]!=0) dfs(ac.nxt[st][i],tmp+(char)('a'+i)); }}int main(){ #ifdef shuaishuai freopen("C:\\Users\\hasee\\Desktop\\a.txt","r",stdin); //freopen("C:\\Users\\hasee\\Desktop\\b.txt","w",stdout);#endif int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); ac.init(); for(int i=0;i<n;i++){ scanf("%s",s); ac.inset(s); }// dfs(0);
ac.debug(); ac.build(); // dfs1(0);// for(int i=0;i<ac.l;i++)// { printf("%d\n",ac.ed[i]);// for(int j=0;j<26;j++)printf("%d ",ac.nxt[i][j]);// printf("\n");// } ac.debug(); scanf("%s",s); printf("%d\n",ac.query(s)); } return 0;}