题目描述

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. SAE实践——用SVN命令行同步/提交代码

    1. 同步应用到本地 注:首次使用svn需要输入安全认证密码 在终端输入以下命令 svn co https://svn.sinaapp.com/nyhello nyhello替换为自己的应用名称. 用 ...

  2. QuantLib 金融计算——基本组件之 InterestRate 类

    目录 QuantLib 金融计算--基本组件之 InterestRate 类 InterestRate 对象的构造 一些常用的成员函数 如果未做特别说明,文中的程序都是 Python3 代码. Qua ...

  3. java 面试大全

    一.CoreJava 部分: 基础及语法部分: 1.面向对象的特征有哪些方面? [基础] 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地 ...

  4. Solr学习笔记(5)—— Spring Data Solr入门

    一.Spring Data Solr简介 前面已经介绍了通过solrJ来操作solr,那么我们如何将Solr的应用集成到Spring中?Spring Data Solr就是为了方便Solr的开发所研制 ...

  5. Matplotlib的初次使用

    # -*- coding: utf-8 -*-#先画一个线性图 import numpy as np import matplotlib.pyplot as plt x=[0,1] y=[0,1] p ...

  6. Great Expectations

    Dear friend, This game is created based on Dicken's Great Expectations. To colorful the contents, I ...

  7. 04-树6 Complete Binary Search Tree (30 分)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  8. SpringMVC初写(六)静态资源设置

    众所周知,SpringMVC的DispatchServlet是不可以以/*规则拦截请求的,否则会将JSP都拦截了,但有时候我们的请求路径是不能有后缀(Resful风格的接口需要),基于上述情况,我们可 ...

  9. Mac 10.12安装流量监控软件Magican

    说明:Magican这家公司已经不维护了,但是软件是单机版的,可以正常使用,但是有些10.12的机器应该是无法看到每个进程的明细,总速度可以正常显示. 下载: (链接: https://pan.bai ...

  10. PHP加密解密数字,适用于URL加密。

    本博主最近正在建设一个9元包邮的网站,希望各位光临指导一些意见: 9元包邮 http://www.jiubaou.com/ <?php /** * 加密解密类 * 该算法仅支持加密数字.比较适用 ...