#include <bits/stdc++.h>
#define maxn 510000
using namespace std;
int t,n,cnt;
int trie[maxn][26];
int fail[maxn];
int word[maxn];
void init(){
for(int i=0;i<maxn;i++){
for(int j=0;j<26;j++) trie[i][j] = 0;
fail[i] = word[i] = 0;
}
cnt = 0;
}
void insert(string s){
int root = 0;
for(int i=0;i<s.size();i++){
int p = s[i]-‘a‘;
if(!trie[root][p]) trie[root][p] = ++cnt;
root = trie[root][p];
}
word[root]++;
}
void getfail(){
queue<int> q;
for(int i=0;i<26;i++){
if(trie[0][i]){
fail[trie[0][i]] = 0;
q.push(trie[0][i]);
}
}
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int i=0;i<26;i++){
int m = trie[tmp][i];
if(m){
fail[m] = trie[fail[tmp]][i];
q.push(m);
}
else
trie[tmp][i] = trie[fail[tmp]][i];
}
}
}
void query(string s){
int ans = 0;
int root = 0;
for(int i=0;i<s.size();i++){
root = trie[root][s[i]-‘a‘];
for(int j = root; j ; j = fail[j]){
if(word[j]){
ans += word[j];
word[j] = 0;
}
}
}
printf("%d\n",ans);
}
int main(){
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=0;i<n;i++){
string s;
cin>>s;
insert(s);
}
getfail();
string s;
cin>>s;
query(s);
}
}
原文:https://www.cnblogs.com/popodynasty/p/14401235.html