AC自动机求调
  • 板块学术版
  • 楼主dvsfanjo
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/24 17:31
  • 上次更新2024/11/24 20:00:41
查看原帖
AC自动机求调
1198462
dvsfanjo楼主2024/11/24 17:31

rt 多测板子,不给题应该也看得懂

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e6 + 5, maxm = 1e6 + 5;
char a[maxn], b[maxm];
ll tot, n, m, t, f[maxn], p[maxn], trie[maxn][26], vis[maxn], deg[maxn];
inline void ini() {
	scanf("%lld", &n);
	tot = 0;
	memset(vis, 0, sizeof vis);
	memset(deg, 0, sizeof deg);
	memset(trie, 0, sizeof trie);
	memset(f, 0, sizeof f);
	memset(p, 0, sizeof p);
	return;
}
inline void build_trie() {
	for (int i = 1; i <= n; i++) {
		scanf("%s", (b + 1));
		m = strlen(b + 1);
		ll u = 0;
		for (int j = 1; j <= m; j++) {
			if (!trie[u][b[j] - 'a']) trie[u][b[j] - 'a'] = ++tot;
			u = trie[u][b[j] - 'a'];
		}
		p[i] = u;
	} //build trie
	return;
}
inline void build_fail() {
	queue <ll> q;
	for (int i = 0; i < 26; i++) {
		if (trie[0][i]) q.push(trie[0][i]);
	}
	while (!q.empty()) {
		ll u = q.front();
		q.pop();
		for (int i = 0; i < 26; i++) {
			if (trie[u][i]) {
				f[trie[u][i]] = trie[f[u]][i];
				q.push(trie[u][i]);
			} else {
				trie[u][i] = trie[f[u]][i];
			}
		}
	} //build fail
	return;
}
inline void AC() {
	scanf("%s", (a + 1));
	m = strlen(a + 1);
	queue <ll> q;
	ll u = 0;
	for (int i = 1; i <= m; i++) {
		u = trie[u][a[i] - 'a'];
		vis[u] = true;
	}
	for (int i = 1; i <= tot; i++) deg[f[i]]++;
	for (int i = 1; i <= tot; i++) if (!deg[i]) q.push(i);
	while (!q.empty()) {
		ll u = q.front();
		q.pop();
		if (!u) continue; 
		vis[f[u]] = true;
		deg[f[u]]--;
		if (!deg[f[u]]) q.push(f[u]);
	} //AC auto mechine
	return;
}
inline void get_ans() {
	ll ans = 0;
	for (int i = 1; i <= n; i++) if (vis[p[i]]) ans++;
	printf("%lld\n", ans);
	return;
}
inline void solve() {
	ini();
	build_trie();
	build_fail();
	AC();
	get_ans();
	return;
}
int main() {
	scanf("%lld", &t);
	while (t--) solve(); 
	return 0;
} 
2024/11/24 17:31
加载中...