题目描述
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
输入输出格式
输入格式:
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
输出格式:
一个数表示答案
输入输出样例
输入样例#1:
2
a
aa
aa
输出样例#1:
2
说明
subtask1[50pts]:∑length(模式串)<=10
6,
length(文本串)<=10
6
,n=1;
subtask2[50pts]:∑length(模式串)<=10
6,
length(文本串)<=10
6
;
#include<bits/stdc++.h>
#define N 500010
using namespace std;
queue<int>q;
struct Aho_Corasick_Automaton{
int c[N][26],val[N],fail[N],cnt;
void ins(char *s){
int len=strlen(s);int now=0;
for(int i=0;i<len;i++){
int v=s[i]-'a';
if(!c[now][v])c[now][v]=++cnt;
now=c[now][v];
}
val[now]++;
}
void build(){
for(int i=0;i<26;i++)if(c[0][i])fail[c[0][i]]=0,q.push(c[0][i]);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;i++)
if(c[u][i])fail[c[u][i]]=c[fail[u]][i],q.push(c[u][i]);
else c[u][i]=c[fail[u]][i];
}
}
int query(char *s){
int len=strlen(s);int now=0,ans=0;
for(int i=0;i<len;i++){
now=c[now][s[i]-'a'];
for(int t=now;t&&~val[t];t=fail[t])ans+=val[t],val[t]=-1;
}
return ans;
}
}AC;
int n;char p[1000005];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%s",p),AC.ins(p);
AC.build();
scanf("%s",p);int ans=AC.query(p);
printf("%d\n",ans);
return 0;
}
版权声明:本文为mkopvec原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。