题目描述
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。
读入两个字符串
输出最长公共子串的长度
样例输入
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother
样例输出
27
题解
很直白的一道题。
将两个字符串串接起来,中间用未出现过的字符隔开
然后求height。
二分答案并判断即可。
模板题一道。
1 #include <cstdio> 2 #include <cstring> 3 #define N 200005 4 int ws[N] , wv[N] , wa[N] , wb[N] , sa[N] , r[N] , rank[N] , height[N] , bl[N] , n , m = 28; 5 char str[N]; 6 void da() 7 { 8 int i , j , p , *x = wa , *y = wb , *t; 9 for(i = 0 ; i < m ; i ++ ) ws[i] = 0; 10 for(i = 0 ; i < n ; i ++ ) ws[x[i] = r[i]] ++ ; 11 for(i = 1 ; i < m ; i ++ ) ws[i] += ws[i - 1]; 12 for(i = n - 1 ; i >= 0 ; i -- ) sa[--ws[x[i]]] = i; 13 for(p = j = 1 ; p < n ; j <<= 1 , m = p) 14 { 15 for(p = 0 , i = n - j ; i < n ; i ++ ) y[p ++ ] = i; 16 for(i = 0 ; i < n ; i ++ ) if(sa[i] - j >= 0) y[p ++ ] = sa[i] - j; 17 for(i = 0 ; i < n ; i ++ ) wv[i] = x[y[i]]; 18 for(i = 0 ; i < m ; i ++ ) ws[i] = 0; 19 for(i = 0 ; i < n ; i ++ ) ws[wv[i]] ++ ; 20 for(i = 1 ; i < m ; i ++ ) ws[i] += ws[i - 1]; 21 for(i = n - 1 ; i >= 0 ; i -- ) sa[--ws[wv[i]]] = y[i]; 22 for(t = x , x = y , y = t , x[sa[0]] = 0 , p = i = 1 ; i < n ; i ++ ) 23 { 24 if(y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + j] == y[sa[i] + j]) 25 x[sa[i]] = p - 1; 26 else 27 x[sa[i]] = p ++ ; 28 } 29 } 30 for(i = 1 ; i < n ; i ++ ) rank[sa[i]] = i; 31 for(p = i = 0 ; i < n - 1 ; height[rank[i ++ ]] = p) 32 for(p ? p -- : 0 , j = sa[rank[i] - 1] ; r[i + p] == r[j + p] ; p ++ ); 33 } 34 bool judge(int mid) 35 { 36 int i; 37 for(i = 1 ; i < n - 1 ; i ++ ) 38 if(height[i] >= mid && bl[sa[i]] != bl[sa[i - 1]]) 39 return 1; 40 return 0; 41 } 42 int main() 43 { 44 int i , j , l , le , ri , mid , ans = 0; 45 for(i = 1 ; i <= 2 ; i ++ ) 46 { 47 scanf("%s" , str); 48 l = strlen(str); 49 for(j = 0 ; j < l ; j ++ ) 50 { 51 bl[n] = i; 52 r[n ++ ] = str[j] - ‘a‘ + 1; 53 } 54 r[n ++ ] = 27; 55 } 56 n ++ ; 57 da(); 58 le = 0; 59 ri = n - 1; 60 while(le <= ri) 61 { 62 mid = (le + ri) >> 1; 63 if(judge(mid)) 64 { 65 ans = mid; 66 le = mid + 1; 67 } 68 else ri = mid - 1; 69 } 70 printf("%d\n" , ans); 71 return 0; 72 }
原文:http://www.cnblogs.com/GXZlegend/p/6272977.html