![bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分) bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分)](https://image.shishitao.com:8440/aHR0cHM6Ly9ia3FzaW1nLmlrYWZhbi5jb20vdXBsb2FkL2NoYXRncHQtcy5wbmc%2FIQ%3D%3D.png?!?w=700&webp=1)
/* 求可重叠的至少重复K次的最长字串 以1为下标起点,因为a[i]最大到1000000,所以要先离散一下 二分长度len 然后O(n)检验 后看h[i]是否有连续的一段h[i]大于len的,并且h[i]连续的长度大于K则满足 */ #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; ; int c[maxn],sa[maxn],t1[maxn],t2[maxn],n,m,K,tot,t[maxn],num[maxn],a[maxn],rank[maxn],height[maxn]; bool cmp(int *r, int a, int b, int l){ return r[a]==r[b] && r[a+l]==r[b+l]; } void suffix(int *a, int n, int m){ , *x=t1, *y=t2; ; i<=m; i++) c[i]=; ; i<=n; i++) c[x[i]=a[i]]++; ; i<=m; i++) c[i]+=c[i-]; ; i--) sa[c[x[i]]--]=i; ; j<=n; j<<=){ p=; ; i<=n; i++) y[++p]=i; ; i<=n; i++) if (sa[i]>j) y[++p]=sa[i]-j; ; i<=m; i++) c[i]=; ; i<=n; i++) c[x[y[i]]]++; ; i<=m; i++) c[i]+=c[i-]; ; i--) sa[c[x[y[i]]]--]=y[i]; swap(x,y); x[sa[]]=; p=; ; i<=n; i++) x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p:++p; m=p; if (p>=n) break; } //for (int i=1; i<=n; i++) printf("%d\n", sa[i]); } void get_height(int *a){ ,j; ; i<=n; i++) rank[sa[i]]=i; ; i<=n; i++){ j=sa[rank[i]-]; k?k--:; while (a[j+k]==a[i+k]) k++; height[rank[i]]=k; } //for (int i=1; i<=n; i++) printf("%d\n", height[i]); } int find(int x){ , r=tot, ans; while (l<=r){ ; ; ; } return ans; } bool check(int k){ ; ; i<=n; i++){ if (height[i]>=k) tot++; else{ >=K) ; ; } } >=K) ; ; } int main(){ scanf("%d%d", &n, &K); ; i<=n; i++) scanf("%d", &a[i]),num[i]=a[i]; sort(num+,num++n); tot=; t[++tot]=num[]; ; i<=n; i++) ]) t[++tot]=num[i]; ; i<=n; i++) a[i]=find(a[i]); suffix(a,n,n); get_height(a); ,r=n,ans; while (l<=r){ ; ; ; } printf("%d\n", ans); ; }