ac自动机模板不多说。
注意在for循坏的判断条件里面别写stren(s)
一直超时
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
typedef pair<int, int> pir;
int t;
char s[100];
char kw[1000005];
int cnt = 0;
struct ss{
int next[26];
int fail;
int flag;
}tree[500005];
void insert(int len)
{
int root = 0;
up(i, 0, len)
{
if (!tree[root].next[s[i] - 'a'])
{
tree[root].next[s[i] - 'a'] = ++cnt;
}
root = tree[root].next[s[i]-'a'];
}
tree[root].flag++;
}
void bfs() {
int root = 0;
queue<int >que;
up(i, 0, 26)
{
if (tree[root].next[i])
{
tree[tree[root].next[i]].fail = root;
que.push(tree[root].next[i]);
}
}
while (!que.empty())
{
int pos = que.front();
que.pop();
int j = 0;
up(i, 0, 26)
{
if (tree[pos].next[i])
{
j = tree[pos].fail;
while (j && !tree[j].next[i])
j = tree[j].fail;
if (tree[j].next[i])
{
j = tree[j].next[i];
}
tree[tree[pos].next[i]].fail = j;
que.push(tree[pos].next[i]);
}
else
{
tree[pos].next[i] = tree[tree[pos].fail].next[i];
}
}
}
}
int querry(int len )
{
int ans = 0;
int root = 0;
int j = root;
up(i, 0, len)
{
while (j&&!tree[j].next[kw[i]-'a'])
{
j = tree[j].fail;
}
if (tree[j].next[kw[i] - 'a'])
j = tree[j].next[kw[i] - 'a'];
int temp = j;
while (temp&&tree[temp].flag!=-1)
{
ans += tree[temp].flag;
tree[temp].flag = -1;
temp = tree[temp].fail;
}
}
return ans;
}
int main()
{
cin >> t;
while (t--)
{
int n;
scanf("%d", &n);
cnt = 0;
memset(tree, 0, sizeof(tree));
tree[0].fail = 0;
up(i, 0, n)
{
scanf("%s", s);
int len = strlen(s);
insert(len);
}
bfs();
scanf("%s", kw);
int len = strlen(kw);
cout << querry(len)<<endl;
}
return 0;
}