后缀自动机(SAM)

后缀自动机 \((\text{SAM})\)
题单链接:luogu

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 3000005;
void init() {
}

int tot, np;
int ch[N][26], fa[N], len[N];
i64 siz[N];
vector<int> g[N];
void ins(int c) {
    int p = np;
    np = ++tot;
    siz[np] = 1;
    len[np] = len[p] + 1;
    for (; p && !ch[p][c]; p = fa[p]) {
        ch[p][c] = np;
    }
    if (p == 0) {
        fa[np] = 1;
    } else {
        int q = ch[p][c];
        if (len[q] == len[p] + 1) {
            fa[np] = q;
        } else {
            int nq = ++tot;
            len[nq] = len[p] + 1;
            fa[nq] = fa[q];
            fa[q] = fa[np] = nq;
            for (; p && ch[p][c] == q; p = fa[p]) {
                ch[p][c] = nq;
            }
            memcpy(ch[nq], ch[q], sizeof ch[q]);
        }
    }
}

i64 ans, mx;
void dfs(int u, int pa) {
    for (int v : g[u]) {
        dfs(v, u);
        siz[u] += siz[v];
    }
    if (siz[u] > 1) mx = max(mx, siz[u] * len[u]);
    ans += (len[u] - len[pa]);
}

void solve() {
    tot = np = 1;
    string s; cin >> s;
    for (auto &c : s) {
        ins(c - 'a');
    }
    for (int i = 2; i <= tot; i++) {
        g[fa[i]].push_back(i);
    }
    dfs(1, 0);
    cout << mx << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int _ = 1;
    init();
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}
posted @ 2025-11-01 23:21  grape_king  阅读(5)  评论(0)    收藏  举报