BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )

二分答案m, 后缀数组求出height数组后分组来判断.

------------------------------------------------------------

#include<bits/stdc++.h>

using namespace std;

const int maxn = 20009;

struct HASH {

int id[maxn], N;

HASH() {

N = 0;

}

inline void work() {

sort(id, id + N);

N = unique(id, id + N) - id;

}

inline void add(int x) {

id[N++] = x;

}

inline int hash(int x) {

return lower_bound(id, id + N, x) - id;

}

} h;

int sa[maxn], rank[maxn], height[maxn], S[maxn], cnt[maxn], N, K;

void build_sa() {

int m = h.N, *x = height, *y = rank;

for(int i = 0; i < m; i++) cnt[i] = 0;

for(int i = 0; i < N; i++) cnt[x[i] = S[i]]++;

for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];

for(int i = N - 1; ~i; i--) sa[--cnt[x[i]]] = i;

for(int k = 1; k <= N; k <<= 1) {

int p = 0;

for(int i = N - k; i < N; i++) y[p++] = i;

for(int i = 0; i < N; i++) if(sa[i] >= k) y[p++] = sa[i] - k;

for(int i = 0; i < m; i++) cnt[i] = 0;

for(int i = 0; i < N; i++) cnt[x[i]]++;

for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];

for(int i = N - 1; ~i; i--) sa[--cnt[x[y[i]]]] = y[i];

swap(x, y); p = 1; x[sa[0]] = 0;

for(int i = 1; i < N; i++)

x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;

if(p >= N) break;

m = p;

}

}

void build_height() {

int k = 0;

for(int i = 0; i < N; i++) rank[sa[i]] = i;

for(int i = 0; i < N; i++) {

if(k) k--;

int j = sa[rank[i] - 1];

while(S[i + k] == S[j + k]) k++;

height[rank[i]] = k;

}

}

bool check(int len) {

int cnt = 1;

for(int i = 1; i < N; i++) {

if(height[i] >= len) {

if(++cnt >= K) return true;

} else

cnt = 1;

}

return false;

}

int main() {

scanf("%d%d", &N, &K);

for(int i = 0; i < N; i++) {

scanf("%d", S + i);

h.add(S[i]);

}

h.add(S[N++] = -0x7fffffff);

h.work();

for(int i = 0; i < N; i++)

S[i] = h.hash(S[i]);

build_sa(); build_height();

int L = 0, R = N;

while(L < R) {

int m = (L + R) / 2 + 1;

if(check(m))

L = m;

else

R = m - 1;

}

printf("%d\n", L);

return 0;

}

------------------------------------------------------------

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 640  Solved: 358
[Submit][Status][Discuss]

Description

农夫John发现他的奶牛产奶的质量一直在变动。经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠。我们称之为一个“模式”。 John的牛奶按质量可以被赋予一个0到1000000之间的数。并且John记录了N(1<=N<=20000)天的牛奶质量值。他想知道最长的出现了至少K(2<=K<=N)次的模式的长度。比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次。当K=2时,这个长度为4。

Input

* Line 1: 两个整数 N,K。

* Lines 2..N+1: 每行一个整数表示当天的质量值。

Output

* Line 1: 一个整数:N天中最长的出现了至少K次的模式的长度

Sample Input

8 2
1
2
3
2
3
2
3
1

Sample Output

4

HINT

Source

Gold

时间: 2024-10-09 20:13:44

BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )的相关文章

BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: 561[Submit][Status][Discuss] Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一个0到1000000之间的

BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个"模式". John的牛奶按质量可以被赋予一个0到1000000之间的数.并且John记录了N(1<=N<=20000)天的牛奶质量值.他想知道最长的出现了至少K(2<=K<=N)次的模式的长度.比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次.当K=2时,这个长度为4. Inp

BZOJ 1717 [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组)

[题目链接]http://www.lydsy.com/JudgeOnline/problem.php?id=1717 [题目大意] 求一个最长的串,使得其在母串中出现的次数达到要求 [题解] 二分答案,利用后缀数组求出的height数组进行检验 [代码] #include <cstdio> #include <cstring> using namespace std; const int N=2000010; int n,k,rank[N],sa[N],h[N],tmp[N],cn

bzoj 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式【后缀自动机】

就是后缀自动机的板子嘛..构造完自动机之后拓扑一下,记录size,对于size大于k的点和ans取max #include<iostream> #include<cstdio> #include<cstring> #include<map> using namespace std; const int N=100005; int n,m,a[N],cur=1,cnt=1; int read() { int r=0,f=1; char p=getchar();

[bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)

以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= = 定义(来自关于后缀数组的那篇国家集训队论文..) 后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列SA[1],SA[2],……,SA[n],并且保证Suffix(SA[i])<Suffix(SA[i+1]),1≤i<n. 也就是将S的n个后缀从小到大进行排序之后把排好序的后缀的开头位置顺次放入SA中. height数组:定义height[i]=suffix(sa[i-1])和suffix(sa[

【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 (二分+SA)

求重复k次的最长重复子串,解法见罗穗骞大神的后缀数组论文 1 const maxn=100419; 2 3 var 4 x,y,rank,sa,h,s,num,c:array[0..maxn] of longint; 5 n,time:longint; 6 7 function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; 8 function min(x,y:longint):longint; be

【bzoj】1717 [Usaco2006 Dec]Milk Patterns 产奶的模式

[算法]后缀数组 [题解]后缀数组 由于m太大,先离散化. 然后处理SA和LCP. 最后用单调队列处理即可. 注意实际上队列头尾长度限制是K-1. 删队尾不要删过头 i≥K才能开始统计答案. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=20010; int n,m,s[maxn],x[maxn],y[maxn],base[maxn],

[BZOJ1717][Usaco2006 Dec]Milk Patterns 产奶的模式

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1297  Solved: 705 [Submit][Status][Discuss] Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个"模式". John的牛奶按质量可以被赋予一个0到100

[bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组_二分答案

Milk Patterns 产奶的模式 bzoj-1717 Usaco-2006 Dec 题目大意:给定一个字符串,求最长的至少出现了$k$次的子串长度. 注释:$1\le n\le 2\cdot 10^4$,$2\le k\le n$. 想法:不难想到二分答案,现在我们考虑如何验证. 这里就是后缀数组的一个妙用了. 我们对原串建立后缀数组,观察$ht$数组. 考虑当前二分出来的$mid$.如果有至少连续$k$的$ht$值都不小于$mid$,那么$k$就是合法的. 故此我们直接扫$ht$数组看看