题意
在文本串中有多少个匹配的字符串
#include <iostream>
#include <cstring>
#include <queue>
#include <cstdio>
using namespace std;
const int MAXN=1e4+10;
char str1[55],str2[1000010];
int trie[500010][26];
int isexist[1000010];
int fail[1000010];
int nodenum=2;//从第一层开始因为0层为根
queue<int> que;
int calc(char c)
{
return c-'a';
}
void add(char str[])
{
int len=strlen(str);
int node=1;
for(int i=0;i<len;i++)
{
int c=calc(str[i]);
if(!trie[node][c])
{
trie[node][c]=nodenum++;
}
node=trie[node][c];
}
isexist[node]++;//单词结尾标记
return;
}
void buildFail()
{
while(!que.empty()) que.pop();
for(int i=0;i<26;i++) trie[0][i]=1;
fail[1]=0;
que.push(1);
while(!que.empty())
{
int node=que.front();que.pop();
for(int i=0;i<26;i++)
{
if(!trie[node][i]) trie[node][i]=trie[fail[node]][i];//路劲压缩
else{
fail[trie[node][i]]=trie[fail[node]][i];
que.push(trie[node][i]);
}
}
}
return;
}
int query(char str[])
{
int ans=0;
int node=1;//从第一层开始查找因为0层为根
int len=strlen(str);
for(int i=0;i<len;i++)
{
int c=calc(str[i]);
int temp=trie[node][c];
while(temp>1)
{
if(isexist[temp]) ans+=isexist[temp],isexist[temp]=0;//查找到单词结尾
temp=fail[temp];
}
node=trie[node][c];
}
return ans;
}
int main()
{
int T;cin>>T;
while(T--)
{
nodenum=2;
//memset(fail,0,sizeof(fail));
memset(isexist,0,sizeof(isexist));
memset(trie,0,sizeof(trie));
int k;
scanf("%d",&k);
for(int i=0;i<k;i++)
{
scanf("%s",str1);
add(str1);
}
scanf("%s",str2);
buildFail();
printf("%d\n",query(str2));
}
return 0;
}