(color{Purple}{只是照着敲了一遍,下次再来看吧~})
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+9;
struct Tire{
int fail,zi[26],end;
}AC[maxn];int tot;
void insert(string s)
{
int len=s.length(),now=0;
for(int i=0;i<len;i++)
{
int ch=s[i]-'a';
if(!AC[now].zi[ch]) AC[now].zi[ch]=++tot;
now=AC[now].zi[ch];
}
AC[now].end+=1;
}
void make_fail()
{
queue<int>q;
for(int i=0;i<=25;i++)
if(AC[0].zi[i]!=0)
{
AC[AC[0].zi[i]].fail=0;//指向根节点
q.push(AC[0].zi[i]);
}
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<=25;i++)
{
if(AC[u].zi[i]!=0)
{
AC[AC[u].zi[i]].fail=AC[AC[u].fail].zi[i];
//子节点的fail指针指向父亲fail指针指向的节点的相同子节点
q.push(AC[u].zi[i]);
}
else AC[u].zi[i]=AC[AC[u].fail].zi[i];
//没有子节点,创造子节点指向当前节点fail指针的节点
}
}
}
int AC_automation(string s)//开始AC辣~
{
int len=s.length(),now=0,ans=0;
for(int i=0;i<len;i++)
{
now=AC[now].zi[s[i]-'a'];//向下一层冲!
for(int j=now;j&&AC[j].end!=-1;j=AC[j].fail)
{
ans+=AC[j].end;
AC[j].end=-1;
}
}
return ans;
}
int main()
{
int n;string s;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s;
insert(s);
}
AC[0].fail=0;//结束标志
make_fail();
cin>>s;//模式串读入
cout<<AC_automation(s);
return 0;//谢幕!
}