SPOJ

要注意每个节点去要取更新其fa。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
#define PDD pair<double,double>
#define ull unsigned long long
using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int n;
char s[N];

struct SuffixAutomaton {
    int last, cur, cnt, ch[N<<1][26], id[N<<1], fa[N<<1], dis[N<<1], sz[N<<1], c[N];
    int mx[N<<1], tmp[N<<1];
    SuffixAutomaton() {cur = cnt = 1;}
    void init() {
        for(int i = 1; i <= cnt; i++) {
            memset(ch[i], 0, sizeof(ch[i]));
            sz[i] = c[i] = dis[i] = fa[i] = 0;
        }
        cur = cnt = 1;
    }
    void extend(int c, int id) {
        last = cur; cur = ++cnt;
        int p = last; dis[cur] = id;
        for(; p && !ch[p][c]; p = fa[p]) ch[p][c] = cur;
        if(!p) fa[cur] = 1;
        else {
            int q = ch[p][c];
            if(dis[q] == dis[p]+1) fa[cur] = q;
            else {
                int nt = ++cnt; dis[nt] = dis[p]+1;
                memcpy(ch[nt], ch[q], sizeof(ch[q]));
                fa[nt] = fa[q]; fa[q] = fa[cur] = nt;
                for(; ch[p][c]==q; p=fa[p]) ch[p][c] = nt;
            }
        }
        sz[cur] = 1;
    }
    void getSize(int n) {
        for(int i = 1; i <= cnt; i++) c[dis[i]]++;
        for(int i = 1; i <= n; i++) c[i] += c[i-1];
        for(int i = cnt; i >= 1; i--) id[c[dis[i]]--] = i;
        for(int i = cnt; i >= 1; i--) {
            int p = id[i];
            sz[fa[p]] += sz[p];
        }
    }
    void solve() {
        int idx = 0;
        while(scanf("%s", s + 1) != EOF) {
            n = strlen(s + 1);
            if(!idx) {
                for(int i = 1; i <= n; i++)
                    extend(s[i]-'a', i);
                getSize(n);
                for(int i = 1; i <= cnt; i++) mx[i] = dis[i];
            } else {
                for(int i = 1; i <= cnt; i++) tmp[i] = 0;
                int len = 0, now = 1;
                for(int i = 1; i <= n; i++) {
                    if(ch[now][s[i]-'a']) {
                        now = ch[now][s[i]-'a']; len++;
                    } else {
                        while(now!=1 && !ch[now][s[i]-'a']) now = fa[now];
                        if(now != 1) len = dis[now]+1, now = ch[now][s[i]-'a'];
                        else len = 0;
                    }
                    tmp[now] = max(tmp[now], len);
                }
                for(int i = cnt; i >= 1; i--) {
                    int u = id[i];
                    mx[fa[u]] = max(mx[fa[u]], min(dis[fa[u]], mx[u]));
                }
                for(int i = 1; i <= cnt; i++)
                    mx[i] = min(mx[i], tmp[i]);
            }
            idx++;
        }
        int ans = 0;
        for(int i = 1; i <= cnt; i++)
            ans = max(ans, mx[i]);
        printf("%d
", ans);
    }
} sam;

int main() {
    sam.solve();
    return 0;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/9818372.html