赤裸裸的后缀数组的应用啊。直接将两个串连起来(中间加一个比小写字母小的字符,我学大家,用的‘#’),求出height数组,找最大值即可(得排除两个后缀在同一端的情况)
/* * hdu1403/win.cpp * Created on: 2013-5-20 * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; const int MAXN = 200010; // MAXN > 256 char s[MAXN]; int sa[MAXN], height[MAXN], rank[MAXN], h[MAXN]; int tmp[MAXN], top[MAXN]; int N; void makesa() { // O(N * log N) int i, j, len, na; na = (N < 256 ? 256 : N); memset(top, 0, na * sizeof(int)); for (i = 0; i < N; i++) top[rank[i] = s[i] & 0xff]++; for (i = 1; i < na; i++) top[i] += top[i - 1]; for (i = 0; i < N; i++) sa[--top[rank[i]]] = i; for (len = 1; len < N; len <<= 1) { for (i = 0; i < N; i++) { j = sa[i] - len; if (j < 0) j += N; tmp[top[rank[j]]++] = j; } sa[tmp[top[0] = 0]] = j = 0; for (i = 1; i < N; i++) { if (rank[tmp[i]] != rank[tmp[i - 1]] || rank[tmp[i] + len] != rank[tmp[i - 1] + len]) top[++j] = i; sa[tmp[i]] = j; } memcpy(rank, sa, N * sizeof(int)); memcpy(sa, tmp, N * sizeof(int)); if (j >= N - 1) break; } } void lcp() { // O(4 * N) int i, j, k; for (j = rank[height[i = k = 0] = 0]; i < N - 1; i++, k++) while (k >= 0 && s[i] != s[sa[j - 1] + k]) height[j] = (k--), j = rank[sa[j] + 1]; for(int i = 0; i < N - 1; i++) { h[i] = height[rank[i]]; } } char str[MAXN]; inline bool judge(int x, int l1) { int i = sa[x]; int j = sa[x - 1]; return (i > l1) xor (j > l1); } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif while(scanf("%s%s", s, str) == 2) { int l1 = strlen(s); s[l1] = '#'; s[l1 + 1] = 0; strcat(s, str); N = strlen(s) + 1; makesa(); lcp(); int ans = 0; for(int i = 1; i < N; i++) { if(height[i] > ans) { if(judge(i, l1)) { ans = height[i]; } } } printf("%d\n", ans); } return 0; }