一切开始的地方
AC自动机板子
HDU2222 keywords search
#include <bits/stdc++.h>
using namespace std;
const int SZ= 500003 ;
const int N= 1000003 ;
namespace AC{
int tr[ SZ] [ 26 ] , tot;
int e[ SZ] , fail[ SZ] ;
void init ( ) {
memset ( tr, 0 , sizeof ( tr) ) ;
memset ( e, 0 , sizeof ( e) ) ;
memset ( fail, 0 , sizeof ( fail) ) ;
tot= 0 ;
}
void insert ( char * s) {
int u= 0 ;
for ( int i= 1 ; s[ i] ; i++ ) {
if ( ! tr[ u] [ s[ i] - 'a' ] ) tr[ u] [ s[ i] - 'a' ] = ++ tot;
u= tr[ u] [ s[ i] - 'a' ] ;
}
e[ u] ++ ;
}
queue< int > q;
void build ( ) {
for ( int i= 0 ; i< 26 ; i++ )
if ( tr[ 0 ] [ i] ) q. push ( tr[ 0 ] [ i] ) ;
while ( q. size ( ) ) {
int u= q. front ( ) ;
q. pop ( ) ;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( tr[ u] [ i] )
fail[ tr[ u] [ i] ] = tr[ fail[ u] ] [ i] , q. push ( tr[ u] [ i] ) ;
else
tr[ u] [ i] = tr[ fail[ u] ] [ i] ;
}
}
}
int query ( char * t) {
int u= 0 , res= 0 ;
for ( int i= 1 ; t[ i] ; i++ ) {
u= tr[ u] [ t[ i] - 'a' ] ;
for ( int j= u; j&& e[ j] != - 1 ; j= fail[ j] )
res+ = e[ j] , e[ j] = - 1 ;
}
return res;
}
}
char s[ N] ; int n, ca;
int main ( ) {
scanf ( "%d" , & ca) ;
while ( ca-- ) {
scanf ( "%d" , & n) ;
AC:: init ( ) ;
for ( int i= 1 ; i<= n; i++ ) scanf ( "%s" , s+ 1 ) , AC:: insert ( s) ;
scanf ( "%s" , s+ 1 ) ;
AC:: build ( ) ;
printf ( "%d\n" , AC:: query ( s) ) ;
}
}
洛谷3796 AC自动机(加强版)
#include <bits/stdc++.h>
using namespace std;
const int N= 156 ;
const int SZ= 156 * 80 ;
namespace AC{
int tr[ SZ] [ 26 ] , fail[ SZ] , tot, idx[ SZ] , val[ SZ] ;
int cnt[ N] ;
void init ( ) {
memset ( tr, 0 , sizeof ( tr) ) ;
memset ( fail, 0 , sizeof ( fail) ) ;
memset ( idx, 0 , sizeof ( idx) ) ;
memset ( val, 0 , sizeof ( val) ) ;
memset ( cnt, 0 , sizeof ( cnt) ) ;
tot= 0 ;
}
void insert ( char * s, int id) {
int u= 0 ;
for ( int i= 1 ; s[ i] ; i++ ) {
if ( ! tr[ u] [ s[ i] - 'a' ] ) tr[ u] [ s[ i] - 'a' ] = ++ tot;
u= tr[ u] [ s[ i] - 'a' ] ;
}
idx[ u] = id;
}
queue< int > q;
void build ( ) {
for ( int i= 0 ; i< 26 ; i++ )
if ( tr[ 0 ] [ i] ) q. push ( tr[ 0 ] [ i] ) ;
while ( q. size ( ) ) {
int u= q. front ( ) ;
q. pop ( ) ;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( tr[ u] [ i] )
fail[ tr[ u] [ i] ] = tr[ fail[ u] ] [ i] , q. push ( tr[ u] [ i] ) ;
else tr[ u] [ i] = tr[ fail[ u] ] [ i] ;
}
}
}
int query ( char * t) {
int u= 0 , res= 0 ;
for ( int i= 1 ; t[ i] ; i++ ) {
u= tr[ u] [ t[ i] - 'a' ] ;
for ( int j= u; j; j= fail[ j] ) val[ j] ++ ;
}
for ( int i= 0 ; i<= tot; i++ )
if ( idx[ i] ) res= max ( res, val[ i] ) , cnt[ idx[ i] ] = val[ i] ;
return res;
}
}
char str[ N] [ 80 ] ;
const int L= 1e6 + 6 ;
char text[ L] ;
int main ( ) {
int n;
while ( ~ scanf ( "%d" , & n) && n) {
AC:: init ( ) ;
for ( int i= 1 ; i<= n; i++ ) {
scanf ( "%s" , str[ i] + 1 ) ;
AC:: insert ( str[ i] , i) ;
}
AC:: build ( ) ;
scanf ( "%s" , text+ 1 ) ;
int ans= AC:: query ( text) ;
printf ( "%d\n" , ans) ;
for ( int i= 1 ; i<= n; i++ ) if ( AC:: cnt[ i] == ans) printf ( "%s\n" , str[ i] + 1 ) ;
}
}