POJ 2774 Long Long Message 后缀数组模板题
题意
给定字符串A、B,求其最长公共子串
后缀数组模板题,求出height数组,判断sa[i]与sa[i-1]是否分属字符串A、B,统计答案即可。
#include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> #include <iostream> using namespace std; const int maxn = 200005; char str[maxn]; int num[maxn]; int wa[maxn], wb[maxn], wv[maxn], sum[maxn]; int rank[maxn], sa[maxn], height[maxn]; bool cmp(int *r, int a, int b, int l) { return (r[a] == r[b]) && (r[a+l] == r[b+l]); } void da(int *r, int *sa, int n, int m) { int *x = wa, *y = wb, *t; for (int i = 1; i <= m; ++i) sum[i] = 0; for (int i = 1; i <= n; ++i) sum[x[i]=r[i]] ++; for (int i = 2; i <= m; ++i) sum[i] += sum[i-1]; for (int i = n; i >= 1; --i) sa[sum[x[i]]--] = i; for (int i, j = 1, p = 1; p < n; j *= 2, m = p) { for (p = 0, i = n-j+1; i <= n; ++i) y[++p] = i; for (i = 1; i <= n; ++i) if (sa[i]-j >= 1) y[++p] = sa[i]-j; for (i = 1; i <= n; ++i) wv[i] = x[y[i]]; for (i = 1; i <= m; ++i) sum[i] = 0; for (i = 1; i <= n; ++i) sum[wv[i]] ++; for (i = 2; i <= m; ++i) sum[i] += sum[i-1]; for (i = n; i >= 1; --i) sa[sum[wv[i]]--] = y[i]; for (t = x, x = y, y = t, p = 1, x[sa[1]] = 1, i = 2; i <= n; ++i) x[sa[i]] = cmp(y, sa[i], sa[i-1], j) ? p : ++p; }/* for (int i = 1; i <= n; ++i) printf("%d ", sa[i]); printf("\n");*/ } void calheight(int *r, int *sa, int n) { for (int i = 1; i <= n; ++i) rank[sa[i]] = i;/* for (int i = 1; i <= n; ++i) printf("%d ", rank[i]); printf("\n");*/ int k = 0; for (int i = 1; i <= n; ++i) { if (k > 0) k --; int j = sa[rank[i]-1]; while (r[i+k] == r[j+k] && i+k <= n && j+k <= n) k ++; height[rank[i]] = k; } } int main() { scanf("%s", str); int l1 = strlen(str); for (int i = 1; i <= l1; ++i) num[i] = str[i-1]-'a'+2; num[l1+1] = 1; scanf("%s", str); int l2 = strlen(str); for (int i = 1; i <= l2; ++i) num[l1+1+i] = str[i-1]-'a'+2; da(num, sa, l1+l2+1, 30); calheight(num, sa, l1+l2+1); int ans = 0; for (int i = 3; i <= l1+l2+1; ++i) if ((sa[i] <= l1 && sa[i-1] >= l1+2) || (sa[i-1] <= l1 && sa[i] >= l1+2)) ans = max(ans, height[i]); printf("%d\n", ans); return 0; }
Nothing is impossible!