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. SpringBoot应用的集成测试

    一.概念和定义 进行软件开发的时候,我们会写很多代码,不过,再过六个月(甚至一年以上)你知道自己的代码怎么运作么?通过测试(单元测试.集成测试.接口测试)可以保证系统的可维护性,当我们修改了某些代码时 ...

  2. tcpdump记录

    tcpdump -i eth0 -nn -A -X 'host 192.168.20.82 and port 9080' -i:interface 监听的网卡. -nn:表示以ip和port的方式显示 ...

  3. Python中字符串颜色

    格式:\033[显示方式;前景色;背景色m 说明: 前景色 背景色 颜色 --------------------------------------- 30 40 黑色 31 41 红色 32 42 ...

  4. Django小范围傻瓜总结

    1.母版: layout.html {% block x %}{% endblock %} 2.子版: {% extends 'layout' %} {% block x %}.......{% en ...

  5. 菜鸟容易中的招__setattr__

    class Counter: def __init__(self): self.counter = 0 # 这里会触发 __setattr__ 调用 def __setattr__(self, nam ...

  6. 技巧:如何提升Oracle用户密码的安全性

    环境:Oracle 11.2.0.4 客户需求:主要背景是数据库中有很多业务用户名,且由于部分用户缺乏安全意识,甚至直接将自己的密码设置为和用户名一样,目前客户期望密码设置不要过于简单,最起码别和用户 ...

  7. Drainage Ditches~网络流模板

    Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover ...

  8. C#扩展方法(转)

    扩展方法使您能够向现有类型"添加"方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型." 这是msdn上说的,也就是你可以对String,Int,DataRo ...

  9. [LeetCode] Daily Temperatures 日常温度

    Given a list of daily temperatures, produce a list that, for each day in the input, tells you how ma ...

  10. mysql事务,视图,权限管理,索引,存储引擎(胖胖老师)

    1: 视图什么是视图    视图是一个虚拟表, 它的内容来源于查询的实表, 本身没有真正的数据;视图的作用    对于复杂的查询时,每次查询时都需要编写一些重复的查询代码让编写sql的效率低下, 为了 ...