KMP自动机例题(待学习)
KMP自动机可以在O(1)的时间内计算kmp。
KMP自动机数组kmp_auto[i][j]可以表示第i位为'a'+j时的最长前缀长度(此前缀可以包含自身)。
kmp[i]数组,表示第i位的最长前缀长度(不含自身)
可以有kmp[i]=kmp_auto[kmp[i-1]][str[i]-'a'];
例题:
https://codeforces.com/contest/1721/problem/E
题解:
https://www.bilibili.com/video/BV1Zd4y137qa?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=75ae018f8d1181302d7ea76b60c928f4
代码:
官方:https://codeforces.com/blog/entry/106416

#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<long long, long long> PLL; int kmp[1000020]; int kmp_auto[1000020][26]; void KMP(string& str) { int n = str.size(); kmp[0] = 0; for (int i = 1; i < n; i++) { int j = kmp[i - 1]; while (j > 0 && str[i] != str[j]) j = kmp[j - 1]; if (str[i] == str[j]) j++; kmp[i] = j; } } void YD() { string str; cin >> str; KMP(str); int n = str.size(); for (int i = 0; i < n; i++) { for (int j = 0; j < 26; j++) { if (i > 0 && j != str[i] - 'a') kmp_auto[i][j] = kmp_auto[kmp[i - 1]][j]; else kmp_auto[i][j] = i + (j == str[i] - 'a'); } } int q; cin >> q; vector<vector<int>> ans(q); while (q--) { string t; cin >> t; int m = t.size(); str += t; for (int i = n; i < m + n; i++) { for (int j = 0; j < 26; j++) { if (j != str[i] - 'a') kmp_auto[i][j] = kmp_auto[kmp[i - 1]][j]; else kmp_auto[i][j] = i + 1; } kmp[i] = kmp_auto[kmp[i-1]][str[i]-'a']; ans[q].push_back(kmp[i]); } while (m--) str.pop_back(); } q=ans.size(); for (int i = q - 1; i >= 0; i--) { for (auto res : ans[i]) { cout << res << ' '; } cout << endl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int T = 1; //cin >> T; while (T--) { YD(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)