AC 自动机

好像还算简单(?
Aho-Corasick automaton 多模匹配显然需要建字典树
fail 指针就是找最长的后缀,使它能继续在字典树上匹配
如果叶子节点下一个节点还要往上连边

P3808 AC 自动机(简单版)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" = "<<x<<endl;
const int N = 1e6 + 5;
int n, trie[N][26], num, cnt[N], fail[N];
string s; 
inline ll read(){
	ll s=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){s=(s<<1)+(s<<3)+(c^48);c=getchar();}
	return s*f;
}
void insert(string s){
	int p = 0;
	for(int i=0;i<s.size();i++){
		int c = s[i] - 'a';
		if(!trie[p][c])	trie[p][c] = ++num;
		p = trie[p][c];
	}
	cnt[p]++;
}
void pretreat(){
	queue<int> q;
	for(int i=0;i<26;i++)if(trie[0][i])q.push(trie[0][i]);
	while(!q.empty()){
		int h = q.front();
		q.pop();
		for(int i=0;i<26;i++){
			if(trie[h][i]){
				fail[trie[h][i]] = trie[fail[h]][i];
				q.push(trie[h][i]);
			}else trie[h][i] = trie[fail[h]][i];
		}
	}
}
int main(){
	n = read();
	for(int i=1;i<=n;i++){
		cin >> s;
		insert(s);
	}
	pretreat();
	cin >> s;
	int p = 0, ans = 0;
	for(int i=0;i<s.size();i++){
		int c = s[i] - 'a';
		p = trie[p][c];
		for(int t = p;t && ~cnt[t];t = fail[t])ans += cnt[t], cnt[t] = -1;
	}
	cout << ans;
	return 0;
}
posted @ 2026-01-22 11:02  今添  阅读(0)  评论(0)    收藏  举报