这道题真的是不想说什么了,数组没开够tmd报TLE,艹,白浪费老子一个小时的大好时光_________________________________
这道题建出ac自动机之后顺着next指针跳(代码中用fail直接代替了),每个点都加上一个标记只能算一次就完事了QAQ
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
struct Trie
{
Trie *son[26],*fail;
bool match;
int sum;
Trie()
{
memset(son,0,sizeof(son));
fail=NULL;
match=sum=0;
}
}*root=new Trie();
void my_insert(char *s)
{
Trie *o=root;
while(*s)
{
int x=(*s)-'a';
if(!o->son[x]) o->son[x]=new Trie();
o=o->son[x];
s++;
}
o->sum++;
}
void bfs()
{
static Trie* dui[1200000];
int top=1,my_final=1;
for(int i=0;i<26;i++)
{
if(root->son[i])
{
dui[my_final++]=root->son[i];
root->son[i]->fail=root;
}
else root->son[i]=root;
}
while(top<my_final)
{
Trie *o=dui[top];
for(int i=0;i<26;i++)
{
if(o->son[i])
{
dui[my_final++]=o->son[i];
o->son[i]->fail=o->fail->son[i];
}
else o->son[i]=o->fail->son[i];
}
top++;
Trie *mid=o->fail;
while(mid!=root && !mid->sum) mid=mid->fail;
o->fail=mid;
}
}
int find_ans(char *s)
{
Trie *o=root;
int ans=0;
while(*s)
{
o=o->son[(*s)-'a'];
Trie *t=o;
while(t!=root && !t->match)
{
t->match=true;
ans+=t->sum;
t=t->fail;
}
s++;
}
return ans;
}
char s[1000101];
int main()
{
int hahaha;
scanf("%d",&hahaha);
for(int h=1;h<=hahaha;h++)
{
int n;
scanf("%d",&n);
root=new Trie();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
my_insert(s);
}
bfs();
scanf("%s",s);
printf("%d\n",find_ans(s));
}
return 0;
}