[板子]字串-KMP與AC自動機
阿新 • • 發佈:2020-08-24
KMP
暴跳next
luogu3375
#include <bits/stdc++.h> const int N = 1e6 + 30; int pos; int lena; int lenb; int nx[N]; char a[N]; char b[N]; int main() { std::cin >> a>> b; lena = std::strlen(a); lenb = std::strlen(b); for (int i = 1; i < lenb; ++i) { while (pos != 0 && b[pos] != b[i]) pos = nx[pos]; if (b[pos] == b[i]) ++pos; nx[i + 1] = pos; } pos = 0; for (int i = 0; i < lena; ++i) { while (pos != 0 && b[pos] != a[i]) pos = nx[pos]; if (b[pos] == a[i]) ++pos; if (pos == lenb) printf ("%d\n", i - lenb + 2); } for (int i = 1; i <= lenb; ++i) printf ("%d ", nx[i]); printf ("\n"); return 0; }
AC自動機
tire樹上暴跳fail
詳細學習請搜尋yyb部落格,講的很好
luogu3796
#include <bits/stdc++.h> const int N = 1000000 + 30; int n; int tot; std::string s, str[N]; struct AC { int fail; int end; int vis[28]; }a[N]; struct NODE { int num; int tot; }ans[N]; bool operator <(NODE x, NODE y) { if (x.tot != y.tot) return x.tot > y.tot; else return x.num < y.num; } inline void init(int num) { std::memset(a[num].vis, 0, sizeof(a[num].vis)); a[num].fail = 0; a[num].end = 0; } inline void Insert(int num, std::string strr) { int now = 0; int len = strr.size(); for (int i = 0; i < len; ++i) { if (a[now].vis[strr[i] - 'a'] == 0) { a[now].vis[strr[i] - 'a'] = ++tot; init(tot); } now = a[now].vis[strr[i] - 'a']; } a[now].end = num; } inline void Work_Fail() { int now = 0; std::queue < int > q; for (int i = 0; i < 26; ++i) { if (a[now].vis[i] != 0) { a[a[now].vis[i]].fail = 0; q.push(a[now].vis[i]); } } while (!q.empty()) { now = q.front(); q.pop(); for (int i = 0; i < 26; ++i) { if (a[now].vis[i] != 0) { a[a[now].vis[i]].fail = a[a[now].fail].vis[i]; q.push(a[now].vis[i]); } else a[now].vis[i] = a[a[now].fail].vis[i]; } } } inline void Work_Ans(std::string strr) { int now = 0; int len = strr.size(); for (int i = 0; i < len; ++i) { now = a[now].vis[strr[i] - 'a']; for (int t = now; t != 0; t = a[t].fail) ++ans[a[t].end].tot; } } int main() { while (37373737) { std::cin >> n; if (n == 0) return n; tot = 0; init(0); for (int i = 1; i <= n; ++i) { std::cin >> str[i]; ans[i] = (NODE){i, 0}; Insert(i, str[i]); } Work_Fail(); std::cin >> s; Work_Ans(s); std::sort(&ans[1], &ans[n + 1]); std::cout << ans[1].tot<< std::endl<< str[ans[1].num]<<std::endl; for (int i = 2; i <= n; ++i) if (ans[i].tot == ans[i - 1].tot) std::cout << str[ans[i].num]<<std::endl; else break; } }
luogu3808
#include <bits/stdc++.h> const int N = 1000000 + 30; int n; int tot; std::string s; struct AC { int fail, end, vis[28]; }a[N]; inline void Insert(std::string str) { int now = 0; int len = str.size(); for (int i = 0; i < len; ++i) { if (a[now].vis[str[i] - 'a'] == 0) a[now].vis[str[i] - 'a'] = ++tot; now = a[now].vis[str[i] - 'a']; } ++a[now].end; } inline void Work_Fail() { int now = 0; std::queue < int > q; for (int i = 0; i < 26; ++i) { if (a[now].vis[i] != 0) { a[a[now].vis[i]].fail = 0; q.push(a[now].vis[i]); } } while (!q.empty()) { now = q.front(); q.pop(); for (int i = 0; i < 26; ++i) { if (a[now].vis[i] != 0) { a[a[now].vis[i]].fail = a[a[now].fail].vis[i]; q.push(a[now].vis[i]); } else a[now].vis[i] = a[a[now].fail].vis[i]; } } } int Work_Ans(std::string str) { int now = 0, ans = 0; int len = str.size(); for (int i = 0; i < len; ++i) { now = a[now].vis[str[i] - 'a']; for (int t = now; t != 0 && a[t].end != -1; t = a[t].fail) { ans += a[t].end; a[t].end = -1; } } return ans; } int main() { std::cin >> n; for (int i = 1; i <= n; ++i) { std::cin >> s; Insert(s); } Work_Fail(); std::cin >> s; printf ("%d\n", Work_Ans(s)); return 0; }