给定 n 个长度不超过 50 的由小写英文字母组成的单词,以及一篇长为 m 的文章。
请问,有多少个单词在文章中出现了。
#include <bits/stdc++.h>
using namespace std;
const int N= 10010 , S= 55 , M= 1000010 ;
char str[ M] ;
int tr[ N* S] [ 26 ] , q[ N* S] , idx;
int cnt[ N* S] ;
int ne[ N* S] ;
void add ( )
{
int p= 0 ;
for ( int i= 0 ; str[ i] ; i++ )
{
int t= str[ i] - 'a' ;
if ( ! tr[ p] [ t] ) tr[ p] [ t] = ++ idx;
p= tr[ p] [ t] ;
}
cnt[ p] ++ ;
}
void bfs ( ) {
int hh= 0 , tt= - 1 ;
for ( int i= 0 ; i< 26 ; i++ )
if ( tr[ 0 ] [ i] )
q[ ++ tt] = tr[ 0 ] [ i] ;
while ( hh<= tt)
{
int t= q[ hh++ ] ;
for ( int i= 0 ; i< 26 ; i++ )
{
int j= ne[ t] ;
int c= tr[ t] [ i] ;
if ( ! c) continue ;
while ( j && ! tr[ j] [ i] ) j= ne[ j] ;
if ( tr[ j] [ i] ) j= tr[ j] [ i] ;
ne[ c] = j;
q[ ++ tt] = c;
}
}
}
int main ( )
{
int t;
cin>> t;
while ( t-- )
{
memset ( cnt, 0 , sizeof cnt) ;
memset ( ne, 0 , sizeof ne) ;
memset ( tr, 0 , sizeof tr) ;
int n;
cin>> n;
for ( int i= 0 ; i< n; i++ ) {
scanf ( "%s" , str) ;
add ( ) ;
}
bfs ( ) ;
scanf ( "%s" , str) ;
int res= 0 ;
for ( int i= 0 , j= 0 ; str[ i] ; i++ )
{
int c= str[ i] - 'a' ;
while ( j && ! tr[ j] [ c] ) j= ne[ j] ;
if ( tr[ j] [ c] ) j= tr[ j] [ c] ;
int p= j;
while ( p)
{
res+ = cnt[ p] ;
cnt[ p] = 0 ;
p= ne[ p] ;
}
}
cout<< res<< endl;
}
return 0 ;
}