P3796 【模板】AC 自动机(加强版)
P3796
差不多还是AC自动机的模板,不过求解得问题不同,这里trie树节点end维护以该点结尾的单词的编号,这样方便我们统计每个模式串出现的次数,最后找到次数最多的模式串即可。
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; struct trie { int fail; int vis[30]; int end; }ac[N]; #define ac(x, i) ac[x].vis[i] int n, tot = 0; struct node { int num, pos; }ans[N]; bool operator < (node a, node b) { return (a.num == b.num) ? a.pos < b.pos : a.num > b.num; } string s[N]; void build(string s, int Num) { int len = s.length(); int p = 0; for (int i = 0; i < len; i ++) { if (ac(p, s[i] - 'a') == 0) ac(p, s[i] - 'a') = ++ tot; p = ac(p, s[i] - 'a'); } ac[p].end = Num;//标记结尾处单词的编号 } void getfail() { queue<int> q; for (int i = 0; i < 26; i ++) { if (ac(0, i) != 0) { ac[ac(0, i)].fail = 0; q.push(ac(0, i)); } } while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < 26; i ++) { if (ac(u, i) != 0) { ac[ac(u, i)].fail = ac(ac[u].fail, i); q.push(ac(u, i)); } else ac(u, i) = ac(ac[u].fail, i); } } } void query(string s) { int len = s.length(); int p = 0; for (int i = 0; i < len; i ++) { p = ac(p, s[i] - 'a'); for (int k = p; k; k = ac[k].fail) ans[ac[k].end].num ++; } } int main() { while(1) { scanf("%d", &n); if (n == 0) break; memset((void *) &ac, 0x00, sizeof ac); tot = 0; for (int i = 1; i <= n; i ++) { cin >> s[i]; ans[i].num = 0; ans[i].pos = i; build(s[i], i); } ac[0].fail = 0; getfail(); cin >> s[0];//文本串 query(s[0]); sort(ans + 1, ans + n + 1); cout << ans[1].num << '\n'; cout << s[ans[1].pos] << '\n'; for (int i = 2; i <= n; i ++) { if (ans[i].num == ans[i - 1].num) cout << s[ans[i].pos] << '\n'; else break; } } return 0; }
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!