模板
class Aho_Corasick {
public:
static const int MAXN = 1e4*50+10;
int nxt[MAXN][26], fail[MAXN], end[MAXN];
int root, L;
Aho_Corasick ( ) { };
int newnode ( ) {
for ( int i = 0; i < 26; i++ )
nxt[L][i] = -1;
end[L++] = 0;
return L-1;
}
void init ( ) {
L = 0;
root = newnode ( );
}
void insert ( char buf[] ) {
int len = strlen ( buf );
int now = root;
for ( int i = 0; i < len; i++ ) {
if ( nxt[now][buf[i] - 'a'] == -1 )
nxt[now][buf[i] - 'a'] = newnode ( );
now = nxt[now][buf[i] - 'a'];
}
end[now]++;
}
void build ( ) {
queue<int>Q;
fail[root] = root;
for ( int i = 0; i < 26; i++ )
if ( nxt[root][i] == -1 )
nxt[root][i] = root;
else {
fail[nxt[root][i]] = root;
Q.push ( nxt[root][i] );
}
while ( !Q.empty ( ) ) {
int now = Q.front ( );
Q.pop ( );
for ( int i = 0; i < 26; i++ )
if ( nxt[now][i] == -1 )
nxt[now][i] = nxt[fail[now]][i];
else {
fail[nxt[now][i]] = nxt[fail[now]][i];
Q.push ( nxt[now][i] );
}
}
}
long long query ( char buf[] ) {
int len = strlen ( buf ), now = root; long long res = 0;
for ( int i = 0; i < len; i++ ) {
now = nxt[now][buf[i] - 'a'];
int temp = now;
while ( temp != root ) {
res += end[temp];
end[temp] = 0;
temp = fail[temp];
}
}
return res;
}
}ac;
理解
一个详细讲解的博客
另一个详解的博客
一篇非常详细的讲ac自动机的博客
kuangbin大神的AC自动机总结