#include <iostream>
#include<cstdio>
#include <queue>
#include <string.h>
using namespace std;
const int N=1e6+1;
int ne[N][27];
int book[N],tu[N];
struct trie
{
int cnt=1;
void add(string s)
{
int ts=1;int len=s.size();
for(int i=0;i<len;i++)
{
if(ne[ts][s[i]-'a']==0){ne[ts][s[i]-'a']=++cnt;ts=cnt;}
else
ts=ne[ts][s[i]-'a'];
// cout<<ts<<" ";
}
//cout<<"\n";
book[ts]++;
}
void makefail()
{
queue<int> qu;
for(int i=0;i<26;i++) ne[0][i]=1;
qu.push(1);
while(!qu.empty())
{
int t=qu.front();qu.pop();
for(int i=0;i<26;i++)
{
if(ne[t][i])
{
qu.push(ne[t][i]);
tu[ne[t][i]]=ne[tu[t]][i];
}
else ne[t][i]=ne[tu[t]][i];
}
}
}
int find(string s)
{
int ans=0;int t=1;
int len=s.size();
for(int i=0;i<len;i++)
{
int v=t;
while(v)
{
if(ne[v][s[i]-'a']!=0){ans+=book[ne[v][s[i]-'a']]; book[ne[v][s[i]-'a']]=0;}
//累计答案
v=tu[v];
}
v=t;
t=ne[t][s[i]-'a'];//更新位置
}
return ans;
}
};
int main()
{
int n;
cin>>n;
string s;
trie tr;
for(int i=1;i<=n;i++)
{
cin>>s;
tr.add(s);
}
string t;
cin>>t;
tr.makefail();
cout<<tr.find(t);
return 0;
}
book是累计的终点,tu是fail数组
总体结构跟题解差不多
为啥第一个点就TLE了。。。QAQ