回文自动机

后言

  • 其实没啥想说的,就是注意我们实际上是对奇数偶数根互相为 fail 的。
  • 也就是 fail[0]=1,fail[1]=0
  • 还有就是,先算 fail 再令 \(ts[pos][c]=n\) 要不可能会出现自己连自己的情况,就不好了。
#include <iostream>
using namespace std;
const int N = 500500, M = 26; char s[N];
int ts[N][M], fail[N], len[N], num[N], idx = 1, lst;
int Fail(int u, int i) { while (s[i - u[len] - 1] != s[i])u = fail[u]; return u; }
int extend(int lst, int c, int p)
{
    int pos = Fail(lst, p);
    if (ts[pos][c])return ts[pos][c];
    const int n = ++idx;
    fail[n] = ts[Fail(fail[pos], p)][c];
    ts[pos][c] = n; len[n] = len[pos] + 2;
    num[n] = num[fail[n]] + 1; return n;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    cin >> s + 1; len[1] = -1; fail[0] = 1;
    for (int i = 1, lst = 0, ans = 0;s[i];i++)
    {
        if (i > 1)s[i] = (s[i] + ans - 97) % 26 + 97;
        lst = extend(lst, s[i] - 'a', i);
        cout << (ans = num[lst]) << ' ';
    }
    return 0;
}
posted @ 2025-04-23 08:01  LUHCUH  阅读(15)  评论(0)    收藏  举报