pku 1743

#include<stdio.h> #include<string.h> #include<stdlib.h> const int maxn = 20005; int wn[maxn],wa[maxn],wb[maxn],wv[maxn],a[maxn],sa[maxn],rank[maxn],height[maxn]; char r[maxn]; int n; int Max(int x,int y){return x>y?x:y;} int Min(int x,int y){return x>y?y:x;} int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i = 0; i < m; ++ i) wn[i] = 0; for(i = 0; i < n; ++ i) wn[x[i]=r[i]]++; for(i = 1; i < m; ++ i) wn[i] += wn[i-1]; for(i = n - 1; i >= 0; --i) sa[--wn[x[i]]] = i; for(p = 1,j = 1; p < n; j *= 2,m = p) { for(p = 0,i = n-j; i < n; ++ i) y[p++] =i; for(i = 0; i < n; ++ i) if(sa[i]>=j) y[p++] = sa[i] - j; for(i = 0; i < m; ++ i) wn[i] = 0; for(i = 0; i < n; ++ i) wn[wv[i]=x[y[i]]]++; for(i = 1; i < m; ++ i) wn[i] += wn[i-1]; for(i = n - 1; i >= 0; --i) sa[--wn[wv[i]]] = y[i]; for(t = x,x = y,y = t,x[sa[0]] = 0,p=1,i=1; i<n; ++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } } void calheight(int *r,int *sa,int n) { int i,j,k = 0; for(i = 1; i <= n; ++ i){ rank[sa[i]] = i; height[i] = 0;} for(i = 0; i < n; height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1]; r[i+k]==r[j+k];++k); } int check(int x) { int min = n,max = 0,i; for(i = 1; i < n; ++ i) { if(height[i]<x) { min = n; max = 0; }else{ min = Min(min,sa[i-1]); max = Max(max,sa[i-1]); min = Min(min,sa[i]); max = Max(max,sa[i]); if(max-min>x)return 1; } }return 0; } int main() { int i,j,k; while(scanf("%d",&n)!=EOF&&n) { scanf("%d",a+0); for(i = 1; i < n; ++ i) { scanf("%d",a+i); a[i-1] = a[i] - a[i-1] + 100; } a[n-1] = 0; da(a,sa,n,256); calheight(a,sa,n-1); int low = 0,high = n-1,mid; while(low<high - 1){ mid = (low + high)>>1; if(check(mid)) low = mid; else high = mid; } if(low>=4)printf("%d\n",low+1); else puts("0"); }return 0; }
后缀数组