二分答案,利用height数组进行判定。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=20000+10; 6 const int maxvalue=1000000+10; 7 int s[maxn]; 8 int sa[maxn],t[maxn],t2[maxn],c[maxvalue],n; 9 int rank[maxn],height[maxn]; 10 void build_sa(int m) 11 { 12 int i,*x=t,*y=t2; 13 for(i=0;i<m;i++) c[i]=0; 14 for(i=0;i<n;i++) c[x[i]=s[i]]++; 15 for(i=1;i<m;i++) c[i]+=c[i-1]; 16 for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; 17 18 for(int k=1;k<=n;k<<=1) 19 { 20 int p=0; 21 for(i=n-k;i<n;i++) y[p++]=i; 22 for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; 23 24 for(i=0;i<m;i++) c[i]=0; 25 for(i=0;i<n;i++) c[x[y[i]]]++; 26 for(i=0;i<m;i++) c[i]+=c[i-1]; 27 for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; 28 29 swap(x,y); 30 p=1;x[sa[0]]=0; 31 for(i=1;i<n;i++) 32 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; 33 if(p>=n) break; 34 m=p; 35 } 36 } 37 void getHeight() 38 { 39 int i,k=0; 40 for(i=0;i<n;i++) rank[sa[i]]=i; 41 for(i=0;i<n;i++) 42 { 43 if(k) k--; 44 int j=sa[rank[i]-1]; 45 while(s[i+k]==s[j+k]) k++; 46 height[rank[i]]=k; 47 } 48 } 49 bool check(int k,int num) 50 { 51 int cnt=0; 52 for(int i=0;i<n;i++) 53 { 54 if(height[i]<k) 55 cnt=0; 56 else 57 { 58 cnt++; 59 if(cnt>=num-1) return true; 60 } 61 } 62 return false; 63 } 64 int main() 65 { 66 int k; 67 while(scanf("%d%d",&n,&k)!=EOF) 68 { 69 int maxv=0; 70 for(int i=0;i<n;i++) 71 { 72 scanf("%d",&s[i]); 73 if(s[i]>maxv) maxv=s[i]; 74 } 75 build_sa(maxv+1); 76 getHeight(); 77 int l=1,r=n/2; 78 int ans=-1; 79 while(l<=r) 80 { 81 int mid=(l+r)>>1; 82 if(check(mid,k)) 83 { 84 ans=mid; 85 l=mid+1; 86 } 87 else 88 r=mid-1; 89 } 90 printf("%d ",ans); 91 } 92 return 0; 93 }