题目描述

Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular patterns in the daily milk quality.

To perform a rigorous study, he has invented a complex classification scheme by which each milk sample is recorded as an integer between 0 and 1,000,000 inclusive, and has recorded data from a single cow over N (1 ≤ N ≤ 20,000) days. He wishes to find the longest pattern of samples which repeats identically at least K (2 ≤ K ≤ N) times. This may include overlapping patterns -- 1 2 3 2 3 2 3 1 repeats 2 3 2 3 twice, for example.

Help Farmer John by finding the longest repeating subsequence in the sequence of samples. It is guaranteed that at least one subsequence is repeated at least K times.

农夫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。

                            --by luogu

https://daniu.luogu.org/problem/show?pid=2852



后缀数组查询可重叠出现超过k次的最长子串长度;

可以等价于height数组中所有长度为k-1的区间最小值的最大值;

不严谨的证明:

合法性:

某区间最小值即为该区间和其左端点减一所有子串的公共前缀;

于是她的确出现的k次,是合法的答案;

最优性:

设子串 x为最优答案;

她满足作为k+个后缀的前缀;

则这k+个后缀rank连续,即她们中第一个除外的height可构成一个长度大于等于k-1的区间;

而这个区间会把x贡献到答案上(否则意味着该区间min不是x——与“作为这k+个后缀的前缀”的条件矛盾)

于是得到结论:可以等价于height数组中所有长度为k-1的区间最小值的最大值;

于是可以使用O(n)的单调队列;

然而为什么在luogu的数据下O(nlogn)的二分len的方法并不慢于单调队列?

值得一提的,由于某(shu)些(ju)原(tai)因(shui)本来可能很大的

其实很小,(20多?30多?)......

代码如下:

 #include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=;
int n,m=,k;
int x[MAXN],y[MAXN],c[MAXN],s[MAXN];
int sa[MAXN],rank[MAXN],height[MAXN];
int que[],h,t;
inline void build_sa();
inline void build_height();
inline void in(int &ans)
{
ans=;bool p=false;char ch=getchar();
while((ch>'' || ch<'')&&ch!='-') ch=getchar();
if(ch=='-') p=true,ch=getchar();
while(ch<=''&&ch>='') ans=ans*+ch-'',ch=getchar();
if(p) ans=-ans;
}
int main()
{
int i,j,k,ans=;
in(n),in(k);
for(i=;i<n;i++)
in(s[i]);
build_sa();
build_height();
h=,t=;
for(i=;i<n;i++){
while(h<t&&height[que[t]]>height[i])t--;
que[++t]=i;
if(i>=k-){
if(height[que[h+]]>ans)ans=height[que[h+]];
if(que[h+]<=i-k+)h++;
}
}
printf("%d",ans);
return ;
}
inline void build_sa(){
int i,j,k;
for(i=;i<=m;i++)c[i]=;
for(i=;i<n;i++)c[x[i]=s[i]]++;
for(i=;i<=m;i++)c[i]+=c[i-];
for(i=n-;i>=;i--)sa[--c[x[i]]]=i;
for(k=;k<=n;k<<=){
int num=;
for(i=n-k;i<n;i++)y[num++]=i;
for(i=;i<n;i++)if(sa[i]>=k)y[num++]=sa[i]-k;
for(i=;i<=m;i++)c[i]=;
for(i=;i<n;i++)c[x[i]]++;
for(i=;i<=m;i++)c[i]+=c[i-];
for(i=n-;i>=;i--)sa[--c[x[y[i]]]]=y[i],y[i]=;
swap(x,y);
num=;x[sa[]]=;
for(i=;i<n;i++)
if(y[sa[i]]!=y[sa[i-]]||y[sa[i]+k]!=y[sa[i-]+k])
x[sa[i]]=++num;
else
x[sa[i]]=num;
if(num>n)break;
m=num;
}
}
inline void build_height(){
int i,j,k=;
for(i=;i<n;i++)rank[sa[i]]=i;
for(i=;i<n;i++){
if(!rank[i])continue;
if(k)k--;
j=sa[rank[i]-];
while(j+k<n&&i+k<n&&s[i+k]==s[j+k])k++;
height[rank[i]]=k;
}
}

祝AC

USACO06DEC Milk Patterns——Solution的更多相关文章

  1. [USACO06DEC] Milk Patterns

    题目描述 Farmer John has noticed that the quality of milk given by his cows varies from day to day. On f ...

  2. 解题:USACO06DEC Milk Patterns

    题面 初见SA 用了一个常见的按$height$分组的操作:二分答案,然后按$height$分组,遇到一个$height$小于$mid$的就丢进下一组并更新答案,如果最多的那组不少于$k$个说明可行 ...

  3. BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)

    题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...

  4. luoguP2852 [USACO06DEC]Milk Patterns

    题意 显然如果有一个子串出现过\(k\)次,那么它必定是一个至少长为k的后缀序的\(LCP\),求出所有相邻的长为\(k-1\)的\(height\)数组的最小值,在其中取最大值即可 code: #i ...

  5. [洛谷P2852] [USACO06DEC]牛奶模式Milk Patterns

    洛谷题目链接:[USACO06DEC]牛奶模式Milk Patterns 题目描述 Farmer John has noticed that the quality of milk given by ...

  6. 【BZOJ-1717】Milk Patterns产奶的模式 后缀数组

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

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

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

  8. POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次

    Milk Patterns   Description Farmer John has noticed that the quality of milk given by his cows varie ...

  9. POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)+后缀数组模板

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7586   Accepted: 3448 Cas ...

随机推荐

  1. 48.rocketMQ

    一.简介 RocketMQ是阿里旗下的一款产品,分为开源版本和非开源版本.相比于ActiveMQ,RocketMQ支持顺序消费.事务机制.失败重试机制.消息可查询.消息订阅.较强的水平扩展能力.亿级堆 ...

  2. Oracle数据库学习(二):Oracle Linux下oracle、ogg的挂载与参数配置

    准备工作:打开虚拟机端的Oracle Linux Server 6.9的系统,然后使用root用户登录.打开终端界面,输入ifconfig -a查看IP地址. 然后在本地打开XShell软件使用以下命 ...

  3. python学习,day3:函数式编程,带参数

    # coding=utf-8 # Author: RyAn Bi def test(x,y,z): print(x) print(y) print(z) test(y=2,z =3,x=1) #形参与 ...

  4. jmeter之beanshell断言实例

    .首先储存一个接口的响应结果,比如在http请求的后面添加beanshell后置处理器(BeanShell PostProcessor)来储存http请求的响应结果: import org.json. ...

  5. 20190415 OSX系统安装和配置maven

    1.下载maven包[apache-maven-3.6.0-bin.zip] 2.解压到准备安装的目录,我的在:/Users/apple/Documents/javasource/apache-mav ...

  6. 第3章—高级装配—配置profile bean

    配置profile bean 3.1.@profile注解是spring提供的一个用来标明当前运行环境的注解. 我们正常开发的过程中经常遇到的问题是,开发环境是一套环境,qa测试是一套环境,线上部署又 ...

  7. SSM的XML和WEB.XML的配置

    显示层(handler/controller): request请求到springmvc的前端控制器,从处理器映射器找相应的handler(用@RequestMapping("  " ...

  8. HTTP协议浅谈

    一.介绍: http 即 超文本传送协议  (Hypertext transfer protocol) 是通过因特网传送万维网文档的数据传送协议.今天普遍使用的一个版本——HTTP 1.1. HTTP ...

  9. 阅读The Java® Language Specification需要知道的术语

    Null Pointer Exception,简称NPE 在java中,static final修饰的是常量.根据编译器的不同行为,常量又可分为编译时常量和运行时常量. 举例说明吧 public st ...

  10. JavaScript数据结构-7.链表

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...