#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
//ac_automaton algorithm
const int MAXNODE = 550000;
const int SIGMA_SIZE = 26;
int fail[MAXNODE]; //失配数组
int last[MAXNODE]; //后缀链接
int ans;
//构造trie
int ch[MAXNODE][SIGMA_SIZE]; //将单词存储在ch中
int val[MAXNODE]; //每个单词出现的个数
int sz; //节点编号
void init()
{
ans = 0;
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void insert(char *s)
{
int u = 0;
int len = strlen(s);
for(int i = 0; i < len; ++i)
{
int c = s[i] - 'a';
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u]++;
}
//计算last后缀链接
void getFail()
{
queue<int> q;
fail[0] = 0;
for(int c = 0; c < SIGMA_SIZE; c++)
{
int u = ch[0][c];
if(u)
{
fail[u] = 0; q.push(u); last[u] = 0;
}
}
while(!q.empty())
{
int r = q.front(); q.pop();
for(int c = 0;c < 26;c++)
{
int u = ch[r][c];
if(!u){ ch[r][c] = ch[fail[r]][c]; continue;}
q.push(u);
int v = fail[r];
while(v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
//cout << last[r] <<endl;
}
}
void solve(int j)
{
//cout << j <<endl;
if(!j) return;
if(val[j])
{
ans += val[j];
val[j] = 0;
}
solve(last[j]);
}
void find(char* T)
{
int len = strlen(T),j = 0;
getFail();
for(int i = 0; i < len; i++)
{
j = ch[j][T[i] - 'a'];
//cout << val[j] <<endl;
if(val[j]) solve(j);
else if(last[j]) solve(last[j]);
}
}
AC自动机模板(多模式匹配)
最新推荐文章于 2021-08-13 10:44:40 发布