#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int N=1000000+5;
struct node{
int son[26],fail,sum;
bool vis;
}trie[N];
int tot,ans;
void init(){
for(int j=0;j<=tot;j++){
trie[j].fail=trie[j].sum=trie[j].vis=0;
for(int i=0;i<26;i++)
trie[j].son[i]=0;
}
/*
memset(trie,0,sizeof(trie));//这种方法爆内存
trie[0].fail=trie[0].sum=trie[0].vis=0;//这种方法TLE
for(int i=0;i<26;i++)
trie[0].son[i]=0;
*/
tot=ans=0;
}
void Insert(char *s){
int p=0;
for(int i=0,len=strlen(s);i<len;i++){
int t=s[i]-'a';
if(!trie[p].son[t])
trie[p].son[t]=++tot;
p=trie[p].son[t];
}
trie[p].sum++;
}
void build_ac(){
queue<int> Q;
for(int i=0;i<26;i++)
if(trie[0].son[i])
Q.push(trie[0].son[i]);
while(!Q.empty()){
int t=Q.front();Q.pop();
for(int i=0;i<26;i++){
int tmp=trie[t].son[i];
if(!tmp)continue;
int f=trie[t].fail;
while(f&&!trie[f].son[i])
f=trie[f].fail;
trie[tmp].fail=trie[f].son[i];
Q.push(tmp);
}
}
}
int Query(char *str){
int p=0,ret=0;
for(int i=0,len = strlen(str);i<len;i++){
int t=str[i]-'a';
while(p && !trie[p].son[t])
p=trie[p].fail;
p=trie[p].son[t];
int tmp=p;
while(tmp && !trie[tmp].vis){
ret+=trie[tmp].sum;
trie[tmp].vis=true;
tmp=trie[tmp].fail;
}
}
return ret;
}
int T,n;
char s[55],str[N];
int main(){
cin>>T;
while(T--){
init();
scanf("%d",&n);
while(n --){
scanf(" %s",s);
Insert(s);
}
build_ac();
scanf(" %s",str);
printf("%d\n",Query(str));
}
return 0;
}
hdu2222Keywords Search
最新推荐文章于 2021-05-18 10:56:21 发布