You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <iostream>
using namespace std ;
const int N = 1000010 ;
int n ; // n个模式串
char s [ N ] ; //模式串
char T [ N ] ; //文本串
// Trie树
int tr [ N ] [ 26 ] , idx ;
int cnt [ N ] ;
void insert ( char * s , int x ) {
int p = 0 ;
for ( int i = 0 ; s [ i ] ; i + + ) {
int t = s [ i ] - ' a ' ;
if ( ! tr [ p ] [ t ] ) tr [ p ] [ t ] = + + idx ;
p = tr [ p ] [ t ] ;
}
cnt [ p ] + + ; //以p为结束节点的字符串个数+1,如果有重复的,这里++也是OK的~
}
// AC自动机
int q [ N ] , ne [ N ] ;
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 p = q [ hh + + ] ;
for ( int i = 0 ; i < 26 ; i + + ) {
int t = tr [ p ] [ i ] ; //此处直接优化为Trie图, 没有采用原始的while向上递归处理的办法, 记忆这个版本即可
if ( ! t )
tr [ p ] [ i ] = tr [ ne [ p ] ] [ i ] ;
else {
ne [ t ] = tr [ ne [ p ] ] [ i ] ;
q [ + + tt ] = t ;
}
}
}
}
//查询字符串s中 n个模式串出现了几个
int query ( char * s ) {
int p = 0 ;
int res = 0 ;
for ( int i = 0 ; s [ i ] ; i + + ) {
p = tr [ p ] [ s [ i ] - ' a ' ] ;
for ( int j = p ; j ; j = ne [ j ] ) {
if ( cnt [ j ] = = - 1 ) break ;
res + = cnt [ j ] ;
cnt [ j ] = - 1 ;
}
}
return res ;
}
int main ( ) {
//加快读入
ios : : sync_with_stdio ( false ) , cin . tie ( 0 ) ;
cin > > n ;
//构建Trie树
for ( int i = 1 ; i < = n ; i + + ) {
cin > > s ;
insert ( s , i ) ;
}
//构建AC自动机
bfs ( ) ;
//输入文本串
cin > > T ;
//输出模式串出现的个数(注意:不是次数,是个数)
printf ( " %d \n " , query ( T ) ) ;
return 0 ;
}