终于搞懂了AC自动机
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
#include<string.h>
using namespace std;
const int maxn = 500005;
char str[maxn*2];
struct node{
int fail;
int cnt;
int next[27];
}tree[maxn];
int k =0,ans = 0;
queue<int>q;
void build_tree(int id , char *s){
int len = strlen(s);
int j = 0;
for(int i =0;i<len;++i){
j = s[i] - 'a';
if(tree[id].next[j]==0){
tree[id].next[j]=++k;
}
id = tree[id].next[j];
}
tree[id].cnt++;
}
void build_fail(int id){
while(!q.empty())q.pop();
for(int i =0;i<26;++i){
int j = tree[id].next[i];
if(j!=0){
q.push(j);
tree[j].fail = id;
}
}
while(!q.empty()){
int now = q.front();
q.pop();
for(int i =0;i<26;++i){
int j = tree[now].next[i];
if(j==0){
tree[now].next[i]=tree[tree[now].fail].next[i];
continue;
}
tree[j].fail = tree[tree[now].fail].next[i];
q.push(j);
}
}
}
void solve(int id,char *s){
int len = strlen(s),j=0;
for(int i =0;i<len;++i){
int j =tree[id].next[s[i]-'a'];
while(j&&tree[j].cnt!=-1){
ans+=tree[j].cnt;
tree[j].cnt=-1;
j = tree[j].fail;
}
id = tree[id].next[s[i]-'a'];
}
}
int main(){
int t;
cin>>t;
while(t--){
memset(tree,0,sizeof(tree));
k=0,ans=0;
int n;
cin>>n;
ans = 0;
for(int i =0;i<n;++i){
scanf("%s",str);
build_tree(0,str);
}
scanf("%s",str);
build_fail(0);
solve(0,str);
cout<<ans<<endl;
}
}