Suffix automaton template

#include <bits/stdc++.h>

using namespace std;

#define ll long long

const int maxn = 1e6 + 5;

ll ans = 0;

namespace SAM {
    struct Node {
        int ch[26], fa, val;
        int len;
        Node(int len=0) : len(len), fa(-1), val(0) {
            memset(ch, 0, sizeof(ch));
        }
    } st[maxn << 1];
    int last, pt;
    void init() {
        st[last = pt = 0] = Node(0);
    }
    void extend(int v, int l) {
        int p = last, cur = ++pt;
        st[cur] = Node(l);
        st[cur].val = 1;
        for (; ~p && !st[p].ch[v]; p = st[p].fa) st[p].ch[v] = cur;
        if (p == -1) st[cur].fa = 0;
        else {
            int q = st[p].ch[v];
            if (st[p].len + 1 == st[q].len) st[cur].fa = q;
            else {
                int copy = ++pt;
                memcpy(&st[copy], &st[q], sizeof(Node));
                st[copy].len = st[p].len + 1;
                st[copy].val = 0;
                st[q].fa = copy;
                st[cur].fa = copy;
                for (; ~p && st[p].ch[v] == q; p = st[p].fa) st[p].ch[v] = copy;
            }
        }
        last = cur;
    }
    int d[maxn << 1], q[maxn << 1], s, t;
    void solve() {
        q[s = t = 0] = 0; d[0] = 1;
        for (register int i = 1; i <= pt; i++) d[st[i].fa]++;
        for (register int i = 0; i <= pt; i++) if (!d[i]) q[t++] = i;
        for (; s < t; ) {
            int u = q[s++];
            st[st[u].fa].val += st[u].val; 
            if (!--d[st[u].fa]) q[t++] = st[u].fa;
            if (st[u].val > 1) ans = max(ans, (ll)st[u].val * st[u].len);
        }
    }
}

char s[maxn];

int main() {
    freopen("ques.in", "r", stdin);
    freopen("ques.out", "w", stdout);
    scanf("%s", s);
    SAM::init();
    for (register int i = 0, end = strlen(s); i < end; i++)
        SAM::extend(s[i] - 'a', i+1);

    SAM::solve();

    printf("%lld", ans);

    return 0;
}

Guess you like

Origin www.cnblogs.com/ac-evil/p/11257066.html