回文树(回文自动机, PAM)板子

仅保存模板:

//我慢は要らない、壊し尽くす
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double db;
typedef vector<int> vi;
typedef pair<int, int> pii;
const int N = 500000 + 100;
const db pi = acos(-1.0);
#define lowbit(x) ((x) & (-x))
#define sqr(x) (x) * (x)
#define rep(i,a,b) for (int i = a; i <= b;i++)
#define per(i,a,b) for (int i = a; i >= b;i--)
#define go(u,i) for (register int i = head[u], v = sq[i].to; i; i = sq[i].nxt, v=sq[i].to)
#define fir first
#define sec second
#define mkp make_pair
#define pb push_back
#define maxd 998244353
#define eps 1e-8

int n, ch[N][26], fa[N], siz[N], len[N], tot, lst, a[N];
char s[N];

int getFail(int x, int m) {
    while (a[m - len[x] - 1] != a[m]) {
        x = fa[x];
    }
    return x;
}

void insert(int x, int id) {
    //cout << "char " << x << endl;
    int p = getFail(lst, id);
    if (!ch[p][x]) {
        tot++;
        len[tot] = len[p] + 2;
        int q = getFail(fa[p], id);
        //cout << "fa " << p << " " << q << endl;
        fa[tot] = ch[q][x];
        siz[tot] = siz[fa[tot]] + 1;
        ch[p][x] = tot;
    }
    lst = ch[p][x];
}

int main() {
    a[0] = 26;
    scanf("%s", s + 1);
    n = strlen(s + 1);
    len[0] = 0; len[1] = -1;
    fa[0] = 1; fa[1] = 0;
    tot = 1;
    int ans = 0;
    rep(i, 1, n) {
        a[i] = (s[i] - 'a' + ans) % 26;
        insert(a[i], i);
        ans = siz[lst];
        printf("%d ", ans);
    }
    return 0;
}
posted @ 2022-03-10 23:39  EncodeTalker  阅读(57)  评论(0编辑  收藏  举报