试个模板- -
/*
HDU 2222 - Keywords Search [ AC自动机 ]
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
const int SIZE = 26;
struct Trie {
int ch[N][SIZE];
int f[N], last[N], cnt[N], val[N];
int tot, ans;
void init() {
tot = 0;
memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val));
}
int ord(char c) {
return c-'a';
}
void insert(char* s) {
int now = 0, n = strlen(s);
for (int i = 0; i < n; i++) {
int t = ord(s[i]);
if (!ch[now][t]) ch[now][t] = ++tot;
now = ch[now][t];
}
val[now]++;
}
void getFail() {
queue<int> Q;
f[0] = 0;
for (int t = 0; t < SIZE; t++) {
int now = ch[0][t];
if (now) {
f[now] = last[now] = 0;
Q.push(now);
}
}
while (!Q.empty()) {
int k = Q.front(); Q.pop();
for (int t = 0; t < SIZE; t++) {
int now = ch[k][t];
if(!now) continue;
Q.push(now);
int nxt = f[k];
while (nxt && !ch[nxt][t]) nxt=f[nxt];
f[now] = ch[nxt][t];
last[now] = val[f[now]] ? f[now] : last[f[now]];
}
}
}
void add(int now) {
for (; now; now = last[now]) ans += val[now], val[now] = 0;
}
void Find(char* s) {
int now = 0, n = strlen(s);
ans = 0;
for (int i = 0; i < n; i++) {
int t = ord(s[i]);
while (now && !ch[now][t]) now = f[now];
now = ch[now][t];
if (val[now]) add(now);
else if (last[now]) add(last[now]);
}
}
}ac;
char s[1000005];
int main()
{
int t; scanf("%d", &t);
while (t--)
{
ac.init();
int n; scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%s", s);
ac.insert(s);
}
ac.getFail();
scanf("%s", s);
ac.Find(s);
printf("%d\n", ac.ans);
}
}
#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
struct Tire {
int ch[N][26], f[N], tot;
int val[N], vis[N];
void init() {
tot = 0;
memset(ch, 0, sizeof(ch));
memset(f, 0, sizeof(f));
memset(val, 0, sizeof(val));
}
int ord(char c) {
return c - 'a';
}
void insert(char* s) {
int now = 0, n = strlen(s);
for (int i = 0; i < n; i++)
{
int t = ord(s[i]);
if (!ch[now][t]) ch[now][t] = ++tot;
now = ch[now][t];
}
val[now]++;
}
void buildFail()
{
queue<int> Q;
f[0] = 0;
for (int t = 0; t < 26; t++) {
int now = ch[0][t];
if (now) {
Q.push(now);
f[now] = 0;
}
}
while (!Q.empty()) {
int now = Q.front(); Q.pop();
for (int t = 0; t < 26; t++) {
int v = ch[now][t];
if (!v) {ch[now][t] = ch[f[now]][t]; continue; }
Q.push(v);
int nxt = f[now];
while (nxt && !ch[nxt][t]) nxt = f[nxt];
f[v] = ch[nxt][t];
}
}
}
int Find(char *s) {
int ans = 0;
int n = strlen(s), now = 0;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++)
{
int t = ord(s[i]);
// while (now && !ch[now][t]) now = f[now];
now = ch[now][t];
int tmp = now;
while (tmp)
{
if (vis[tmp]) break;
vis[tmp] = 1;
ans += val[tmp];
val[tmp] = 0;
tmp = f[tmp];
}
}
return ans;
}
}ac;
char s[1000005];
int t, n;
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
ac.init();
while (n--)
{
scanf("%s", s);
ac.insert(s);
}
ac.buildFail();
scanf("%s", s);
printf("%d\n", ac.Find(s));
}
}