题目链接:
https://vjudge.net/problem/HDU-2222
题意:
给n个模式串,一个文本串,问有多少个 模式串在文本串中 出现了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+5;
int trie[maxn][26],fail[maxn],tot;
int sum[maxn];
char s[maxn*2];
bool visit[maxn];
void ins(char *s){
int len=strlen(s);
int p=0;
for(int i=0;i<len;i++){
int c=s[i]-'a';
if(!trie[p][c]){
trie[p][c]=++tot;
}
p=trie[p][c];
}
sum[p]++;
}
void get_fail(){
queue<int> q;
for(int i=0;i<26;i++){
if(trie[0][i]){
q.push(trie[0][i]);
}
}
while(q.size()){
int x=q.front();
q.pop();
for(int i=0;i<26;i++){
if(!trie[x][i]){
trie[x][i]=trie[fail[x]][i];
}else{
fail[trie[x][i]]=trie[fail[x]][i];
q.push(trie[x][i]);
}
}
}
}
int ac(char* s){
int p=0,ans=0;
int len=strlen(s);
for(int i=0;i<len;i++){
int id=s[i]-'a';
int y=trie[p][id];
while(y&&sum[y]!=-1){
ans+=sum[y];
sum[y]=-1;
y=fail[y];
}
p=trie[p][id];
}
return ans;
}
void init(){
tot=0;
memset(sum,0,sizeof sum);
memset(trie,0,sizeof trie);
memset(fail,0,sizeof fail);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
init();
int n;
scanf("%d",&n);
while(n--){
scanf("%s",s);
ins(s);
}
get_fail();
scanf("%s",s);
printf("%d\n",ac(s));
}
return 0;
}