HDU 2222 (AC自动机模板题)

时间:2022-06-27 16:30:04

题意:

给一个文本串和多个模式串,求文本串中一共出现多少次模式串

分析:

ac自动机模板,关键是失配函数

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
#define N 250010
const ll INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod = ;
struct Trie{
int ch[N][],val[N],f[N],last[N],num;
void init(){
num=;
memset(ch,,sizeof(ch));
memset(val,,sizeof(val));
memset(f,,sizeof(f));
memset(last,,sizeof(last));
}
void print(int j){
if(j){
printf("%d: %d\n", j, val[j]);
print(last[j]);
}
}
void build(char *s){
int u=,len=strlen(s);
for(int i=;i<len;++i)
{
int v=s[i]-'a';
if(!ch[u][v]){
memset(ch[num],,sizeof(ch[num]));
ch[u][v]=num++;
}
u=ch[u][v];
}
val[u]++;
}
  //失配函数
void getfail(){
queue<int>q;
for(int i=;i<;++i)
if(ch[][i])
q.push(ch[][i]);
while(!q.empty()){
int r=q.front();
q.pop();
for(int i=;i<;++i)
{
int u=ch[r][i];
if(!u)continue;
q.push(u);
int v=f[r];
while(v&&!ch[v][i])v=f[v];
f[u]=ch[v][i];
last[u]=val[f[u]]?f[u]:last[f[u]];
}
}
}
int find(char *T){
int u=,len=strlen(T);
int total=;
for(int i=;i<len;++i){
int v=T[i]-'a';
while(u&&ch[u][v]==)
u=f[u];
u=ch[u][v];
int tmp=u;
while(tmp&&val[tmp]){
total+=val[tmp];
val[tmp]=;
tmp=f[tmp];
}
}
return total;
}
}ac;
int main()
{
char s[],T[];
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
ac.init();
while(n--){
scanf("%s",s);
ac.build(s);
}
ac.getfail();
scanf("%s",T);
printf("%d\n",ac.find(T));
}
return ;
}