【HDOJ】1403 Longest Common Substring
后缀数组2倍增可解。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 #define MAXM 28 6 #define MAXN 100010 7 8 int wa[MAXN*2]; 9 int wb[MAXN*2]; 10 int wv[MAXN*2]; 11 int ws[MAXN*2]; 12 char s[MAXN]; 13 int str[MAXN*2], sa[MAXN*2]; 14 int height[MAXN*2], rank[MAXN*2]; 15 16 bool cmp(int *r, int a, int b, int l) { 17 return r[a]==r[b] && r[a+l]==r[b+l]; 18 } 19 20 void da(int *r, int *sa, int n, int m) { 21 int i, j, *x = wa, *y = wb, *t; 22 int p; 23 24 for (i=0; i<m; ++i) ws[i] = 0; 25 for (i=0; i<n; ++i) ws[x[i]=r[i]]++; 26 for (i=1; i<m; ++i) ws[i] += ws[i-1]; 27 for (i=n-1; i>=0; --i) sa[--ws[x[i]]] = i; 28 for (j=1, p=1; j<n; j*=2, m=p) { 29 for (p=0, i=n-j; i<n; ++i) y[p++] = i; 30 for (i=0; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j; 31 for (i=0; i<n; ++i) wv[i] = x[y[i]]; 32 for (i=0; i<m; ++i) ws[i] = 0; 33 for (i=0; i<n; ++i) ws[wv[i]]++; 34 for (i=1; i<m; ++i) ws[i] += ws[i-1]; 35 for (i=n-1; i>=0; --i) sa[--ws[wv[i]]] = y[i]; 36 for (t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i<n; ++i) 37 x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++; 38 } 39 } 40 41 void calheight(int *r, int *sa, int n) { 42 int i, j, k=0; 43 44 for (i=1; i<=n; ++i) rank[sa[i]] = i; 45 for (i=0; i<n; height[rank[i++]]=k) 46 for (k?k--:0, j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k) 47 /*do nothing*/; 48 } 49 50 void printRank(int n) { 51 int i; 52 53 printf("\nprint rank...\n"); 54 for (i=0; i<n; ++i) 55 printf("%d ", rank[i]); 56 printf("\n"); 57 } 58 59 void printSa(int n) { 60 int i; 61 62 printf("\nprint sa...\n"); 63 for (i=0; i<n; ++i) 64 printf("%d ", sa[i]); 65 printf("\n"); 66 } 67 68 void printHeight(int n) { 69 int i; 70 71 printf("\nprint height...\n"); 72 for (i=0; i<n; ++i) 73 printf("%d ", height[i]); 74 printf("\n"); 75 } 76 77 int main() { 78 int l1, l2, l; 79 int i, j, k; 80 int ans; 81 82 #ifndef ONLINE_JUDGE 83 freopen("data.in", "r", stdin); 84 #endif 85 86 while (scanf("%s", s) != EOF) { 87 l = 0; 88 for (l1=0; s[l1]; l1++) 89 str[l++] = s[l1] - 'a' + 2; 90 str[l++] = 1; // split two strings 91 scanf("%s", s); 92 for (l2=0; s[l2]; l2++) 93 str[l++] = s[l2] - 'a' + 2; 94 str[l] = 0; 95 da(str, sa, l+1, MAXM); 96 calheight(str, sa, l); 97 #ifndef ONLINE_JUDGE 98 printRank(l+1); 99 printSa(l+1); 100 printHeight(l); 101 #endif 102 ans = -1; 103 for (i=2; i<=l; ++i) { 104 if (height[i] > ans) { 105 if ((sa[i-1]<l1 && sa[i]>l1) || (sa[i-1]>l1 && sa[i]<l1)) 106 ans = height[i]; 107 } 108 } 109 printf("%d\n", ans); 110 } 111 112 113 return 0; 114 }