算法学习:回文自动机
Posted rentu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法学习:回文自动机相关的知识,希望对你有一定的参考价值。
【定义】
【自动机】
【前置知识】
【AC自动机】
【manacher】
其实不学这两个也可以,但是学过之后会更方便理解
【解决问题】
主要解决回文串的问题
能求出 字符串中回文子串的长度和出现次数
#include<cstdio> #include<iostream> #include<algorithm> #include<string> #define ll long long using namespace std; const int mod = 19930726; const int MAXN = 1000010; ll k; int n, cnt; int now; struct note int son[26]; ll len; int siz; trie[MAXN]; int fail[MAXN], pos; bool operator<(note a, note b) return a.len > b.len; char s[MAXN]; int get(int x) while (s[pos] != s[pos - trie[x].len - 1]) x = fail[x]; return x; void insert(int x) int cur = get(now); if (!trie[cur].son[x]) int u = ++cnt; trie[u].len = trie[cur].len + 2; fail[u] = trie[get(fail[cur])].son[x]; trie[cur].son[x] = u; trie[trie[cur].son[x]].siz++; now = trie[cur].son[x]; ll poww(ll a, int b) ll res = 1; while (b) if (b & 1) res = (res*a) % mod; a = (a*a) % mod; b = b >> 1; return res; void init() fail[0] = 1; fail[1] = 0; now = 0, cnt = 1; trie[1].len = -1; int main() scanf("%d%lld", &n, &k); scanf("%s", s+1); init(); s[0] = 0; for (pos = 1; pos <= n; pos++) insert(s[pos] - ‘a‘); for (int i = cnt; i >= 2; i--) trie[fail[i]].siz = (trie[fail[i]].siz + trie[i].siz) % mod; //for (int i = 1; i <= cnt; i++) //printf("%lld %d\\n", trie[i].len, trie[i].siz); sort(trie + 1, trie + 1 + cnt); ll ans = 1; int pos = 1; while (k) if (pos > cnt) printf("-1"); return 0; if (trie[pos].len % 2 == 0) pos++; continue; ans = (ans*poww(trie[pos].len, k < trie[pos].siz ? k : trie[pos].siz)) % mod; k -= k < trie[pos].siz ? k : trie[pos].siz; pos++; printf("%lld", ans); return 0;
以上是关于算法学习:回文自动机的主要内容,如果未能解决你的问题,请参考以下文章