于是现在才会写自动机一定是要遭人嘲笑得了。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<algorithm>
#define Clear(s) memset((s),0,sizeof((s)))
using namespace std;
const int N = 1000010;
const int M = 1000010;
struct AC{
int ch[N][26],f[N],last[N];
int val[N],cnt[N];
int top;
void init(){
Clear(ch); Clear(f); Clear(last);
Clear(val); Clear(cnt);
top = 0;
}
void insert(char *T, int num){
int n = strlen(T);
int x = 0;
for(int i = 0; i < n; i++){
int c = T[i]-'a';
if( !ch[x][c] ) ch[x][c] = ++top;
x = ch[x][c];
}
val[x] = num;//说明这个是某个字串的末尾。。。
}
void getfail(){
queue<int> Q;
for(int c = 0; c < 26; c++){
int u = ch[0][c];
if(u) f[u] = 0, last[u] = 0, Q.push(u);
}
while( !Q.empty() ){
int r = Q.front(); Q.pop();
for(int c = 0; c < 26; c++){
int u = ch[r][c];
// if( !u ) continue;
if( !u ){ ch[r][c] = ch[ f[r] ][c]; continue; } //补上所有不存在的边
Q.push(u);
int v = f[r];
while( v && !ch[v][c] ) v = f[v];
f[u] = ch[v][c];
// printf("f[%d] = ch[%d][%d] = %d\n", u,v,c, f[u] );
last[u] = val[ f[u] ] ? f[u]: last[ f[u] ];
}
}
}
void find(char *T){
int n = strlen(T);
int x = 0;
for(int i = 0; i < n; i++){
int c = T[i]-'a';
// while( x && !ch[x][c] ) x = f[x];
x = ch[x][c]; //直接匹配到
// printf("Find: x = %d\n", x );
if( val[x] ) count(x);
else if( last[x] ) count(last[x]);//?? 这个地方似乎写f[x],x都行,,,
}
}
void count(int x){
if(x){
// printf("Count: x = %d\n", x );
cnt[ val[x] ]++;
if( last[x] ) count( last[x] );
}
}
}ac;
map<string,int> mp;
char str[20000][100];
char text[M];
int main(){
int n;
int T;cin>>T;
while(T--)
{scanf("%d",&n);
mp.clear();ac.init();
int tot = 0;
for(int i = 1; i <= n; i++){
scanf("%s", str[i] );
if( mp.count( str[i] ) == 0 ) mp[ str[i] ] = ++tot;
ac.insert( str[i], mp[str[i]] );
}
ac.getfail();
scanf("%s", text);
ac.find( text );
int k = 0;
for(int i = 1; i <= tot; i++) k+=ac.cnt[i];
// k = max( k, ac.cnt[i] );
printf("%d\n", k );
/* for(int i = 1; i <= n; i++){
if( ac.cnt[ mp[str[i]] ] == k )
printf("%s\n", str[i] );
}*/
}
return 0;
}