第一道后缀数组。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxvn=20000+10; 6 int s[maxvn]; 7 int sa[maxvn],t[maxvn],t2[maxvn],c[maxvn]; 8 int rank[maxvn],height[maxvn]; 9 void build(int n,int m) 10 { 11 int i,*x=t,*y=t2; 12 13 for(i=0;i<m;i++) c[i]=0; 14 for(i=0;i<n;i++) 15 c[x[i]=s[i]]++; 16 for(i=1;i<m;i++) c[i]+=c[i-1]; 17 for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; 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(int n) 38 { 39 int i,j,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 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 n,int k) 50 { 51 int maxv=sa[1],minv=sa[1]; 52 for(int i=2;i<=n;i++) 53 { 54 if(height[i]<k)maxv=minv=sa[i]; 55 else 56 { 57 if(sa[i]<minv)minv=sa[i]; 58 if(sa[i]>maxv)maxv=sa[i]; 59 if(maxv-minv>k)return true; 60 } 61 } 62 return false; 63 } 64 int main() 65 { 66 int i,n; 67 while(scanf("%d",&n)&&n) 68 { 69 for( i=0;i<n;i++) 70 scanf("%d",&s[i]); 71 for(i=0;i<n;i++) 72 s[i]=s[i+1]-s[i]+90; 73 n--; 74 s[n]=0; 75 build(n+1,200); 76 getHeight(n); 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(n,mid)) {ans=mid;l=mid+1;} 83 else r=mid-1; 84 } 85 printf("%d ",ans>=4?ans+1:0); 86 } 87 return 0; 88 }