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。


Input

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

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


Output

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


Sample Input



Sample Output

4

题解:


   看到网上基本上都是用的二分,所以我打算来一篇单调队列的做法!

 

题意:
     题目要求满足重复k次,并且是最长的串的长度;
 

分析:
     首先我们要知道不相邻的两个串的LCP是等于它们之间的height值的最小值(LCP定义);其次我们可以发现这样一个性质,假设:
   A
   B
   C
   D
      E
   price:以每个串为开头,长度为k的队列的值;
  
(根据SA数组从小到大排列的height数组)且此时k=2,如果参与答案中的最后一个串为E,那么答案就是D到E之间的
 
height值的最小值;再假设最后一个串为B,那么答案为A到B之间的height值的最小值;到这里你有没有一点点头绪呢?^_^ 我
 
们的答案就是在以每个串为头(或者尾),以k为身长的一个队列中,再根据上面的性质,每个price是它队身中height值的最小
 
值;我们只要找出最小的price就是我们的答案了! 可能你会问不是要求至少吗?其实你可以想想,我们在已经满足了k的条件
 
后,如果我们再继续增加队身的长度,如果进来的一个height比当前的price大,那么的对我们的price没有影响(因为上面的性
 
质);如果来一个height比当前price小,那么会我们的price变小,这不符合我们的需要,所以证明;所以我们只需要O(n)的进
 
行单调队列维护最小值,求得一个最小的price即可!
 

注意:
    因为数据可能很大,所以需要离散化一下!
 

代码:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int len,m,ki;
int str[];
int rank[],buc[],SA[],y[];
int belong[],cnt;
void suffix()
{
m=len;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[rank[i]=belong[str[i]]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) SA[--buc[rank[i]]]=i;
for(int k=;k<len;k<<=)
{
int p=;
for(int i=len-;i>=len-k;i--) y[p++]=i;
for(int i=;i<len;i++) if(SA[i]>=k) y[p++]=SA[i]-k;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[rank[y[i]]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) SA[--buc[rank[y[i]]]]=y[i];
swap(rank,y);p=;
rank[SA[]]=;
for(int i=;i<len;i++)
{
if(y[SA[i-]]==y[SA[i]]&&y[SA[i-]+k]==y[SA[i]+k])
rank[SA[i]]=p-;
else rank[SA[i]]=p++;
}
if(p>=len) break;
m=p;
}
}
int height[];
struct node
{
int place,price;
}t[]; int main()
{
freopen("a.in","r",stdin);
scanf("%d%d",&len,&ki);
int imax=;
for(int i=;i<len;i++)
{
scanf("%d",&str[i]);
belong[str[i]]++;
imax=max(str[i],imax);
}
for(int i=;i<=imax;i++) if(belong[i]) belong[i]=cnt++;
suffix();
int x=;
for(int i=;i<len;i++) rank[SA[i]]=i;
for(int i=;i<len;i++)
{
if(rank[i]==) continue;
if(x) x--;
int j=SA[rank[i]-];
while(str[i+x]==str[j+x]&&x+i<len&&x+j<len) x++;
height[rank[i]]=x;
}
int ans=;
int now=len-;
int l=,r=-;
while(now>=)
{
while(t[l].place-now>=ki-) l++;
while(t[r].price>=height[now]&&r>=l) r--;
t[++r].price=height[now];t[r].place=now;
if(len-now+>=ki)
{
if(t[l].price>ans) ans=t[l].price;
}
now--;
}
printf("%d\n",ans);
return ;
}

未经博主同意,不得私自转载!

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. 【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组

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

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

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

  5. 【刷题】BZOJ 1717 [Usaco2006 Dec]Milk Patterns 产奶的模式

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

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

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

  7. 【bzoj1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组+离散化

    题目描述 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一 ...

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

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

  9. bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分)

    /* 求可重叠的至少重复K次的最长字串 以1为下标起点,因为a[i]最大到1000000,所以要先离散一下 二分长度len 然后O(n)检验 后看h[i]是否有连续的一段h[i]大于len的,并且h[ ...

随机推荐

  1. linux下的Shell编程(6)case和select

    第一个,除了if语句之外,Shell Script中也有类似C语言中多分支结构的case语句,它的语法是: case var in pattern 1 ) - ;; pattern 2 ) - ;; ...

  2. 阿里云API网关(6)用户指南(开放 API )

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  3. python入门(13)获取函数帮助和调用函数

    Python内置了很多有用的函数,我们可以直接调用. 要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数.可以直接从Python的官方网站查看文档: http://doc ...

  4. Linux搭建Apache+Tomcat实现负载均衡

    一.首先需要安装java,详见http://www.cnblogs.com/fun0623/p/4350004.html 二.编译安装Apache,详见http://www.cnblogs.com/f ...

  5. git 添加管理成员

    git 添加管理成员   登录git后的样子: 具体操作流程看截图和说明 : * 图中1:打开设置面板: * 图中2:打开成员面板: * 图中3:添加成员功能标签: * 图中4:添加的成员,这里会弹出 ...

  6. (第一章)对程序员来说CPU是什么

    这几天,看到一本书,<程序是怎么跑起来的>,觉得之前都没有完整的看完一本书,现在要从这本书开始,慢慢的培养自己写读书笔记的习惯,不能度过去就忘了. 学习是一个螺旋上升的过程,不要指望一下子 ...

  7. Java入门1

    一.eclipse的简单使用 1.新建项目 在package explorer的空白处点击右键,新建一个项目(new->Java Project)或者点击菜单栏的File->JavaPro ...

  8. 计算机网络-应用层之HTTP协议

    1.概念 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写:HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等). ...

  9. C#之设计模式之六大原则(转载)

    设计模式之六大原则(转载) 关于设计模式的六大设计原则的资料网上很多,但是很多地方解释地都太过于笼统化,我也找了很多资料来看,发现CSDN上有几篇关于设计模式的六大原则讲述的比较通俗易懂,因此转载过来 ...

  10. 学习ASP.NET Core Razor 编程系列六——数据库初始化

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...