要注意每个节点去要取更新其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\n", ans); } } sam; int main() { sam.solve(); return 0; } /* */