Milk Patterns POJ
阿新 • • 發佈:2018-12-14
先把序列離散化一下 還是二分長度 看height陣列中是否有連續k-1個數大於等於列舉值
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=2e4+10; int ary[maxn],tmp[maxn],rnk[maxn],hgt[maxn],t1[maxn],t2[maxn],sum[maxn],sa[maxn]; int n,k,len; void getsa(int *r,int *sa,int n,int m) { int *x,*y,*t; int i,j,p; x=t1,y=t2; for(i=0;i<m;i++) sum[i]=0; for(i=0;i<n;i++) sum[x[i]=r[i]]++; for(i=1;i<m;i++) sum[i]+=sum[i-1]; for(i=n-1;i>=0;i--) sa[--sum[x[i]]]=i; for(p=1,j=1;p<n;j*=2) { 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++) sum[i]=0; for(i=0;i<n;i++) sum[x[y[i]]]++; for(i=1;i<m;i++) sum[i]+=sum[i-1]; for(i=n-1;i>=0;i--) sa[--sum[x[y[i]]]]=y[i]; t=x,x=y,y=t; x[sa[0]]=0; for(p=1,i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; m=p; } } void getht(int *r,int *rnk,int *hgt,int n) { int i,j,k; k=0; for(i=1;i<=n;i++) rnk[sa[i]]=i; for(i=0;i<n;i++) { if(k) k--; else k=0; j=sa[rnk[i]-1]; while(r[i+k]==r[j+k]) k++; hgt[rnk[i]]=k; } } bool judge(int lim,int n) { int maxx,cnt,i; maxx=1,cnt=1; for(i=2;i<=n;i++) { if(hgt[i]>=lim) cnt++; else cnt=1; maxx=max(maxx,cnt); } if(maxx>=k) return 1; else return 0; } int main() { int i,l,r,m,ans; while(scanf("%d%d",&n,&k)!=EOF) { for(i=0;i<n;i++) scanf("%d",&ary[i]); for(i=0;i<n;i++) tmp[i]=ary[i]; sort(tmp,tmp+n); len=unique(tmp,tmp+n)-tmp-1; for(i=0;i<n;i++) ary[i]=lower_bound(tmp,tmp+len,ary[i])-tmp+1; ary[n]=0; getsa(ary,sa,n+1,20000); getht(ary,rnk,hgt,n); l=1,r=n,ans=0; while(l<=r) { m=(l+r)/2; if(judge(m,n)) l=m+1,ans=m; else r=m-1; } printf("%d\n",ans); } return 0; }