题意:
给出长度为n的数字序列,求重复出现次数不小于k的最长序列(连续)的长度。
例如序列 1 2 3 2 3 2 3 1,k=2,那么序列2 3 2 3重复出现了两次,长度为4。
分析:
二分枚举长度,如果在height数组中连续出现超过k次的话就满足。
View Code
#include#include #include using namespace std;const int maxn = 1000002;int s[maxn];int sa[maxn],t[maxn],t2[maxn],c[maxn];int N;void build_sa(int n,int m){ int i, *x=t, *y=t2; for (i=0; i =0; i--) sa[--c[x[i]]] = i; int p; for (int k=1; k<=n; k<<=1) { p = 0; for (i=n-k; i = k) y[p++] = sa[i]-k; for (i=0; i =0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x, y); p = 1; x[sa[0]] = 0; for (i=1; i = n) break; m = p; }}int rank[maxn],height[maxn];void getheight(){ int i, j, k = 0; for (i=1; i<=N; i++) rank[sa[i]] = i; for (i=0; i = len){ tot++; if (tot >= k) return true; } else tot = 1; } return false;}void solve(int k){ int i, j; int l, r, mid, res; l = k; r = N; while (l <= r){ mid = (l+r)/2; if (ok(mid, k)){ res = mid; l = mid+1; } else r = mid-1; } printf("%d\n",res);}int main(){ // freopen("in.in","r",stdin); int k, i; while (scanf("%d %d",&N,&k)!=EOF) { for (i=0; i