POJ 3261 字尾陣列
阿新 • • 發佈:2018-11-26
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=20000+100; const int maxm=1000000+100; struct SuffixArray { int s[maxn]; int sa[maxn],rank[maxn],height[maxn]; int t1[maxn],t2[maxn],c[maxm],n; void build_sa(int m) { int i,*x=t1,*y=t2; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[i]=s[i]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; for(i=n-k;i<n;i++) y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++; if(p>=n) break; m=p; } } void build_height() { int i,j,k=0; for(i=0;i<n;i++) rank[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[rank[i]-1]; while(s[i+k]==s[j+k]) k++; height[rank[i]]=k; } } bool check(int l,int k)//長l的出現k次以上的串 { int cnt=0; for(int i=1;i<n;i++) { if(height[i]<l)//新的一組開始 cnt=1; else { cnt++; if(cnt>=k) return true; } } return false; } }sa; int main() { int n,k; while(scanf("%d%d",&n,&k)==2&&n&&k) { for(int i=0;i<n;i++) { scanf("%d",&sa.s[i]); sa.s[i]++; } sa.s[n]=0; sa.n=n+1; sa.build_sa(1000000+2); sa.build_height(); int min=0,max=n; while(min<max) { int mid=min+(max-min+1)/2; if(sa.check(mid,k)) min = mid; else max=mid-1; } printf("%d\n",min); } return 0; }