用后缀自动机实现求两个串的最长公共子串。
#include <cstdio> #include <algorithm> const int N = 500005; char s[N]; int sz,sm,lst,ans,l[N],f[N],ch[N][26]; int main() { scanf("%s", s); for(int i = 0; s[i]; i++) { int c = s[i]-'a', u = lst; for(lst = ++sz, l[sz] = i+1; u && !ch[u][c]; u = f[u]) ch[u][c] = sz; int x = ch[u][c]; if(!x) {ch[u][c] = sz; continue;} if(l[u]+1 == l[x]) {f[sz] = x; continue;} l[++sz] = l[u]+1, f[sz] = f[x], f[x] = f[lst] = sz; for(int j = 0; j < 26; j++) ch[sz][j] = ch[x][j]; for(; u && ch[u][c] == x; u = f[u]) ch[u][c] = sz; if(ch[u][c] == x) ch[u][c] = sz; } scanf("%s", s); for(int i = 0, u = 0; s[i]; i++) { int c = s[i]-'a'; for(; u && !ch[u][c]; sm=l[u=f[u]]); if(ch[u][c]) sm++, u = ch[u][c]; ans = std::max(ans, sm); } printf("%d", ans); return 0; }