模板AC自动机
#include<bits/stdc++.h>
#define maxn 5005
#define ll long long
const ll mod=1e9+7;
using namespace std;
const int N = 1e6+10;
const double pi = acos(-1.0);
struct Tree{
int fail;//失配指针
int vis[26];//子节点的位置
int end;//标记有几个单词以这个节点结尾
}AC[N];//trie树
int cnt = 0;//Trie的指针
inline void Build(string s)
{
int l = s.length();
int now = 0;
for(int i=0;i<l;i++)
{
if(AC[now].vis[s[i]-'a'] == 0)//Trie树没有这个子节点
{
AC[now].vis[s[i]-'a'] = ++cnt;//构造出来
}
now = AC[now].vis[s[i]-'a'];//向下构造
}
AC[now].end += 1;//标记单词结尾
}
void Get_fail()//构造fail指针
{
queue<int>Q;
for(int i=0;i<26;i++)
{
if(AC[0].vis[i]!=0)
{
AC[AC[0].vis[i]].fail = 0;
Q.push(AC[0].vis[i]);
}
}
while(!Q.empty())
{
int u = Q.front();
Q.pop();
for(int i=0;i<26;i++)
{
if(AC[u].vis[i]!=0)
{
AC[AC[u].vis[i]].fail = AC[AC[u].fail].vis[i];
Q.push(AC[u].vis[i]);
}
else
AC[u].vis[i] = AC[AC[u].fail].vis[i];
}
}
}
int AC_Query(string s)
{
int l = s.length();
int now = 0,ans = 0;
for(int i=0;i<l;i++)
{
now = AC[now].vis[s[i]-'a'];
for(int t=now;t&&AC[t].end!=-1;t=AC[t].fail)
{
ans += AC[t].end;
AC[t].end = -1;
}
}
return ans;
}
int main()
{
int n;
string s;
cin >> n;
for(int i=1;i<=n;i++)
{
cin >> s;
Build(s);
}
AC[0].fail = 0;
Get_fail();
cin >> s;
cout << AC_Query(s) << "
";
}