模板
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自动机总结