先输入一堆子串,再输入一个母串
询问有多少个子串在母串中出现过
(模仿的洛谷大佬的板子
//
// Created by xingchaoyue on 2019/4/19.
//
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int maxn = 5000000+10;
using namespace std;
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 n;
scanf("%d",&n);
for(int i =1;i<=n;++i){
scanf("%s",str);
build_tree(0,str);
}
build_fail(0);
scanf("%s",str);
solve(0,str);
printf("%d\n",ans);
return 0;
}