AC自动机模版题:
#include <bits/stdc++.h>
using namespace std;
const char base = 'a';
const int maxkind = 26;
int trie[500005][maxkind];
int fail[500005];
int isword[500005];
int color[500005];
queue<int> q;
int cnt;
int ans;
void init(){
while(!q.empty()) q.pop();
ans = 0;
cnt = 1;
memset(color,0,sizeof(color));
memset(trie,0,sizeof(trie));
memset(fail,0,sizeof(fail));
memset(isword,0,sizeof(isword));
}
void ACtrie(const char* s,const int l){
int p = 0;
for(int i=0;i<l;i++){
int c = s[i] - base;
if(trie[p][c] == 0) trie[p][c] = cnt++;
p = trie[p][c];
}
isword[p]++;
}
void ACfail(){
q.push(0);
int p = 0;
int fp = 0;
while(!q.empty()){
p = q.front();
q.pop();
fp = fail[p];
for(int i=0;i<maxkind;i++){
if(trie[p][i] != 0) q.push(trie[p][i]);
if(trie[p][i] != 0 && trie[fp][i] != 0 && p!=fp){
fail[trie[p][i]] = trie[fp][i];
}
if(trie[p][i] == 0 && trie[fp][i] != 0){
trie[p][i] = trie[fp][i];
}
}
}
}
void ACfind(const char* s,const int l){
int c;
int p = 0;
int f;
for(int i=0;i<l;i++){
c = s[i] - base;
if(trie[p][c]!=0){
p = trie[p][c];
ans += isword[p];
isword[p] = 0;
}else p = fail[p];
f = p;
while(color[f]==0&&f!=0){
color[f] = 1;
ans += isword[f];
isword[f] = 0;
f = fail[f];
}
}
}
int main(){
int t,n;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=0;i<n;i++){
char s[52];
scanf("%s",s);
ACtrie(s,strlen(s));
}
ACfail();
char s[1000005];
scanf("%s",s);
ACfind(s,strlen(s));
printf("%d\n",ans);
}
return 0;
}