1 #include <iostream> 2 #include <string.h> 3 #include<string> 4 #include <queue> 5 using namespace std; 6 typedef long long ll; 7 const int maxn(2*1e6+9); 8 9 int trie[maxn][26];//字典树 10 int cntword[maxn];//记录该单词出现次数 11 int fail[maxn];//失败时的回溯指针 12 int cnt(0); 13 14 void insertWords(string s){ 15 int root(0),next; 16 for(int i=0;i<s.size();i++){ 17 next=s[i]-'a'; 18 if(!trie[root][next]){ 19 trie[root][next]=cnt++; 20 } 21 root=trie[root][next]; 22 } 23 cntword[root]++;//当前节点单词数+1 24 } 25 26 void getFail(){ 27 queue<int>q; 28 for(int i=0;i<26;i++){//将第二层所有出现了的字母扔进队列 29 if(trie[0][i]){ 30 fail[trie[0][i]]=0; 31 q.push(trie[0][i]); 32 } 33 } 34 int now; 35 while(!q.empty()){ 36 now=q.front(); 37 q.pop(); 38 for(int i=0;i<26;i++){ 39 if(trie[now][i]){ 40 if(trie[now][i]){ 41 fail[trie[now][i]]=trie[fail[now]][i]; 42 q.push(trie[now][i]); 43 } 44 else trie[now][i]=trie[fail[now]][i]; 45 } 46 } 47 } 48 } 49 50 int query(string s){ 51 int now(0),ans(0); 52 for(int i=0;i<s.size();i++){ 53 now=trie[now][s[i]-'a']; 54 for(int j=now;j&&cntword[j]!=-1;j=fail[j]){ 55 ans=ans+cntword[j]; 56 cntword[j]=-1; 57 } 58 } 59 return ans; 60 } 61 62 int main(){ 63 int n; 64 string s; 65 cin>>n; 66 for(int i=0;i<n;i++){ 67 cin>>s; 68 insertWords(s); 69 } 70 fail[0]=0; 71 getFail(); 72 cin>>s; 73 cout<<query(s)<<'\n'; 74 return 0; 75 }