Files
python/TangDou/AcWing/AcAutomation/P3808.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

78 lines
1.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 1000010;
int n; // n个模式串
char s[N]; //模式串
char T[N]; //文本串
// Trie树
int tr[N][26], idx;
int cnt[N];
void insert(char *s, int x) {
int p = 0;
for (int i = 0; s[i]; i++) {
int t = s[i] - 'a';
if (!tr[p][t]) tr[p][t] = ++idx;
p = tr[p][t];
}
cnt[p]++; //以p为结束节点的字符串个数+1,如果有重复的,这里++也是OK的~
}
// AC自动机
int q[N], ne[N];
void bfs() {
int hh = 0, tt = -1;
for (int i = 0; i < 26; i++)
if (tr[0][i]) q[++tt] = tr[0][i];
while (hh <= tt) {
int p = q[hh++];
for (int i = 0; i < 26; i++) {
int t = tr[p][i]; //此处直接优化为Trie图,没有采用原始的while向上递归处理的办法,记忆这个版本即可
if (!t)
tr[p][i] = tr[ne[p]][i];
else {
ne[t] = tr[ne[p]][i];
q[++tt] = t;
}
}
}
}
//查询字符串s中 n个模式串出现了几个
int query(char *s) {
int p = 0;
int res = 0;
for (int i = 0; s[i]; i++) {
p = tr[p][s[i] - 'a'];
for (int j = p; j; j = ne[j]) {
if (cnt[j] == -1) break;
res += cnt[j];
cnt[j] = -1;
}
}
return res;
}
int main() {
//加快读入
ios::sync_with_stdio(false), cin.tie(0);
cin >> n;
//构建Trie树
for (int i = 1; i <= n; i++) {
cin >> s;
insert(s, i);
}
//构建AC自动机
bfs();
//输入文本串
cin >> T;
//输出模式串出现的个数(注意:不是次数,是个数)
printf("%d\n", query(T));
return 0;
}