用一个未用过的字符连接两个字符串,求后缀数组相邻项来自不同穿的--最大height值即可。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 char s[200005]; 6 7 int sa[200005],t[200005],t2[200005],c[200005]; 8 void build_sa(int m,int n) 9 { 10 int i,*x=t,*y=t2; 11 //基数排序 12 for (i=0;i<m;i++) c[i]=0; 13 for (i=0;i<n;i++) c[x[i]=s[i]]++; 14 for (i=1;i<m;i++) c[i]+=c[i-1]; 15 for (i=n-1;i>=0;i--) sa[--c[x[i]]]=i; 16 for (int k=1;k<=n;k<<=1) 17 { 18 int p=0; 19 //直接利用sa数组排序第二关键字 20 for (i=n-k;i<n;i++) y[p++]=i; 21 for (i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k; 22 //基数排序第一关键字 23 for (i=0;i<m;i++) c[i]=0; 24 for (i=0;i<n;i++) c[x[y[i]]]++; 25 for (i=0;i<m;i++) c[i]+=c[i-1]; 26 for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; 27 //根据sa和y数组计算新的x数组 28 swap(x,y); 29 p=1; x[sa[0]]=0; 30 for (i=1;i<n;i++) 31 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; 32 if (p>=n) break; 33 m=p;//下次基数排序的最大值 34 } 35 } 36 37 int _rank[200005],height[200005]; 38 void getHeight(int n) 39 { 40 int i,j,k=0; 41 for (i=0;i<=n;i++) _rank[sa[i]]=i; 42 for (i=0;i<n;i++) 43 { 44 if (k) k--; 45 int j=sa[_rank[i]-1]; 46 while (s[i+k]==s[j+k]) k++; 47 height[_rank[i]]=k; 48 } 49 } 50 51 int main() 52 { 53 int len,i,maxx,n; 54 while (~scanf("%s",s)) 55 { 56 len=strlen(s); 57 s[len]='9'; 58 scanf("%s",s+len+1); 59 n=strlen(s); s[n]='0'; 60 build_sa(300,n+1); getHeight(n); 61 // for (i=0;i<n;i++) printf("%d ",sa[i]); 62 maxx=0; 63 for (i=2;i<n;i++) 64 if (height[i]>maxx) 65 if ((sa[i-1]>len&&sa[i]<len)||(sa[i-1]<len&&sa[i]>len)) maxx=height[i]; 66 printf("%d\n",maxx); 67 } 68 }