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

Solution

后缀排序后,得到height数组

发现原串中的每个子串一定是某个后缀的前缀,且不同后缀的前缀对应原串的子串一定不同

那么考虑二分答案,即长度,如果有长度大于等于k的一段height大于等于二分的长度,那么说明存在长度大于等于二分的长度的一个子串出现至少k次

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=20000+10;
int n,k,rk[MAXN],SA[MAXN],nxt[MAXN],cnt[MAXN],height[MAXN],s[MAXN];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void GetSA()
{
int m=300;
for(register int i=1;i<=n;++i)rk[i]=s[i];
for(register int i=1;i<=n;++i)cnt[rk[i]]++;
for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
for(register int i=n;i>=1;--i)SA[cnt[rk[i]]--]=i;
for(register int k=1,ps;k<=n;k<<=1)
{
ps=0;
for(register int i=n-k+1;i<=n;++i)nxt[++ps]=i;
for(register int i=1;i<=n;++i)
if(SA[i]>k)nxt[++ps]=SA[i]-k;
for(register int i=1;i<=m;++i)cnt[i]=0;
for(register int i=1;i<=n;++i)cnt[rk[i]]++;
for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
for(register int i=n;i>=1;--i)SA[cnt[rk[nxt[i]]]--]=nxt[i];
std::swap(rk,nxt);
rk[SA[1]]=1;ps=1;
for(register int i=2;i<=n;rk[SA[i]]=ps,++i)
if(nxt[SA[i]]!=nxt[SA[i-1]]||nxt[SA[i]+k]!=nxt[SA[i-1]+k])ps++;
if(ps>=n)break;
m=ps;
}
for(register int i=1,j,k=0;i<=n;height[rk[i++]]=k)
for(k=k?k-1:k,j=SA[rk[i]-1];s[i+k]==s[j+k];++k);
}
inline bool check(int len)
{
for(register int i=2,nt=1;i<=n;++i)
{
if(height[i]>=len)nt++;
else nt=1;
if(nt>=k)return true;
}
return false;
}
int main()
{
read(n);read(k);
for(register int i=1;i<=n;++i)read(s[i]);
GetSA();
int l=1,r=n,ans=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
write(ans,'\n');
return 0;
}

【刷题】BZOJ 1717 [Usaco2006 Dec]Milk Patterns 产奶的模式的更多相关文章

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

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: ...

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

    二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include&l ...

  3. BZOJ#1717:[Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+单调队列)

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的 ...

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

    [题目链接]http://www.lydsy.com/JudgeOnline/problem.php?id=1717 [题目大意] 求一个最长的串,使得其在母串中出现的次数达到要求 [题解] 二分答案 ...

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

    Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个"模式". ...

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

    就是后缀自动机的板子嘛..构造完自动机之后拓扑一下,记录size,对于size大于k的点和ans取max #include<iostream> #include<cstdio> ...

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

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1469  Solved: ...

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

    [算法]后缀数组 [题解]后缀数组 由于m太大,先离散化. 然后处理SA和LCP. 最后用单调队列处理即可. 注意实际上队列头尾长度限制是K-1. 删队尾不要删过头 i≥K才能开始统计答案. #inc ...

  9. bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

    后缀数组+二分答案+离散化.(上次写的时候看数据小没离散化然后一直WA...写了lsj师兄的写法. #include<cstdio> #include<cstring> #in ...

随机推荐

  1. 流式断言器AssertJ介绍

    本文来自网易云社区 作者:范旭斐 大家在使用testng.junit做自动化测试的过程中,经常会用到testng.junit自带的断言器,有时候对一个字符串.日期.列表进行断言很麻烦,需要借助到jdk ...

  2. 限时购校验小工具&dubbo异步调用实现限

    本文来自网易云社区 作者:张伟 背景 限时购是网易考拉目前比较常用的促销形式,但是前期创建一个限时购活动时需要各个BU按照指定的Excel格式进行选品提报,为了保证提报数据准确,运营需要人肉校验很多信 ...

  3. 吴裕雄 python 机器学习——层次聚类AgglomerativeClustering模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import cluster from sklearn.metrics ...

  4. 如何在Mac OS系统下搭建Java开发环境 配置Java环境变量

    1. 打开终端   在finder里面搜索(这台MAC)查找终端   2. 在cdlouiedeAir:~ cdlouie$(cdlouie是我的电脑用户名) 后面输入sudo vim /etc/pr ...

  5. 安装MySQLdb模块遭遇"fatal error: my_config.h: No such file or directory"的处理

    Issue       I encountered an error when I run the python script which need to import the module of & ...

  6. Qt-QML-C++交互实现文件IO系统-后继-读取XML文件和创建XML文件

    在前面两篇中,大致完成了一个文件IO的读和写操作.前面两篇文章链接 http://blog.csdn.net/z609932088/article/details/71488250 http://bl ...

  7. Selenium(Python)PageObject页面对象

    使用PageObject页面对象的好处是, 当页面元素的位置发生改变时, 只需要去修改Xpath或者ID, 而不用去修改测试用例本身: 本次的思路是: 1.常用方法类 2.页面对象类 3.测试用例类 ...

  8. Web自动化selenium技术快速实现爬虫

    selenium是大家众所周知的web自动化测试框架,主要用来完成web网站项目的自动化测试,但其实如果要实现一个web爬虫,去某些网站爬取数据,其实用selenium来实现也很方便. 比如,我们现在 ...

  9. 编写你自己的Python模块

    其实网上Python教程挺多的,编写你自己的模块很简单,这其实就是你一直在做的事情!这是因为每一个 Python 程序同时也是一个模块.你只需要保证它以 .py 为扩展名即可.下面的案例会作出清晰的解 ...

  10. [JSON].valueOf( keyPath )

    语法:[JSON].valueOf( keyPath ) 返回:[任意类型 | null] 说明:获取键名路径原值,它保留原始值的类型 示例: b = sysFile.binary("tes ...