社区讨论
90pts TLE on#9求条
P3808AC 自动机(简单版)参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mjy1mw27
- 此快照首次捕获于
- 2026/01/03 16:31 2 个月前
- 此快照最后确认于
- 2026/01/06 22:30 上个月
CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
const int ALPHA = 26;
int ch[N][ALPHA];
int fail[N];
int cnt[N]; // cnt[u] 表示以节点 u 结尾的单词个数(或是否为结尾)
int idx = 0;
// 插入一个模式串 s
void insert(const string& s){
int u = 0;
for (char c : s) {
int v = c - 'a';
if (!ch[u][v]) ch[u][v] = ++idx;
u = ch[u][v];
}
cnt[u]++;
}
void build(){
queue<int> q;
// 根的所有直接子节点入队,fail 指向 0
for(int i = 0; i < ALPHA; i++){
if (ch[0][i]) {
fail[ch[0][i]] = 0;
q.push(ch[0][i]);
}
}
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=0; i<ALPHA; i++){
if(ch[u][i]){
int v = ch[u][i];
fail[v] = ch[fail[u]][i]; //利用父节点的 fail 快速转移
q.push(v);
}
else{
ch[u][i] = ch[fail[u]][i]; //把空指针直接指向 fail 的对应子
}
}
}
}
// 在文本串 t 中匹配,返回匹配到的单词总数
int query(const string& t){
int u = 0, res = 0;
for(char c : t){
u = ch[u][c-'a'];
for(int j = u; j; j = fail[j]){ // 沿 fail 链向上统计所有匹配
res += cnt[j];
cnt[j] = 0;
}
}
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for(int i=1; i<=n; i++){
string s;
cin >> s;
insert(s);
}
build();
string t;
cin >> t;
cout << query(t) << '\n';
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...