給定兩個字符串 A, B,求它們的最長公共子串長度。字符串長度 ≤ 100000。
將兩字符串拼接:S = A + '#' + B(# 為不在字符集中的分隔符)。構建 S 的後綴數組 SA 和 Height 數組。Height[i] 表示 SA[i] 和 SA[i-1] 的最長公共前綴。答案為所有 Height[i] 中,對應的兩個後綴分別屬於 A 和 B 的最大值。
O(n log n)。Height 數組 O(n)。i=1..n-1,若 SA[i] 和 SA[i-1] 一個 < lenA,一個 > lenA,更新答案。struct SuffixArray {
int s[maxn], sa[maxn], rk[maxn], ht[maxn];
int t[maxn], t2[maxn], c[maxn];
int n;
void build_sa(int m) { ... } // 倍增法
void build_height() { ... } // 利用 rk 數組
};
int main() {
char A[100010], B[100010];
while (scanf("%s%s",A,B)==2) {
SA sa;
int lenA=strlen(A), lenB=strlen(B);
for (int i=0;ilenA) || (p1>lenA && p2
構建 O(n log n),查詢 O(n),總長 ≤ 200000,輕鬆通過。
POJ 2774 是後綴數組求最長公共子串的經典應用。關鍵在於正確拼接字符串、選擇不衝突的分隔符、以及利用 Height 數組配合來源判斷。掌握倍增法 SA 模板,可解決所有子串/子序列相關問題。