【BZOJ1717】产奶的模式(后缀数组)
【BZOJ1717】产奶的模式(后缀数组)
题面
题解
\(hihocoder\)里面讲的非常好了
这题要求的就是最长可重叠重复K次子串
所谓相同的子串
我们可以理解为如果有两个后缀的前缀相同
那么就有一个相同的子串
如果两个后缀的前缀相同
那么他们在\(SA\)中的排名是接近的
再说清楚点
如果两个后缀的前缀相同
必然是在后缀排序中一段连续的后缀都拥有这个相同的前缀
因此,求出\(height\)数组之后
考虑如何计算答案:
直接搞显然搞不出来
因此二分一下答案
如何\(check\)是否存在长度为\(mid\)的\(K\)重复子串呢?
既然是一段连续的区间
因此,就需要检查是否有超过\(K\)个连续的\(height\)都\(>=mid\)
这个很容易证明:
如果有\(l..r\)的\(height\)都超过了\(mid\)
那么,证明这一段区间中任意两个后缀的
\(LCP\)长度都至少为\(mid\)
所以,此时这个\(mid\)一定出现了超过\(K\)次
所以,大力二分一下即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 1200000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int SA[MAX],Rank[MAX],x[MAX],y[MAX],t[MAX];
int height[MAX],a[MAX];
int n,K;
bool cmp(int i,int j,int k){return y[i]==y[j]&&y[i+k]==y[j+k];}
void GetSA()
{
int m=1000010;
for(int i=1;i<=n;++i)t[x[i]=a[i]]++;
for(int i=1;i<=m;++i)t[i]+=t[i-1];
for(int i=n;i>=1;--i)SA[t[x[i]]--]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=1;i<=n;++i)y[i]=0;
for(int i=n-k+1;i<=n;++i)y[++p]=i;
for(int i=1;i<=n;++i)if(SA[i]>k)y[++p]=SA[i]-k;
for(int i=0;i<=m;++i)t[i]=0;
for(int i=1;i<=n;++i)t[x[y[i]]]++;
for(int i=1;i<=m;++i)t[i]+=t[i-1];
for(int i=n;i>=1;--i)SA[t[x[y[i]]]--]=y[i];
swap(x,y);
x[SA[1]]=p=1;
for(int i=2;i<=n;++i)x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
if(p>=n)break;
m=p;
}
for(int i=1;i<=n;++i)Rank[SA[i]]=i;
for(int i=1,j=0;i<=n;++i)
{
if(j)j--;
while(a[i+j]==a[SA[Rank[i]-1]+j])j++;
height[Rank[i]]=j;
}
}
bool check(int h)
{
int cnt=0;
for(int i=2;i<=n;++i)
{
if(height[i]<h)cnt=0;else cnt++;
if(cnt==K-1)return true;
}
return false;
}
int main()
{
n=read();K=read();
for(int i=1;i<=n;++i)a[i]=read();
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;
}
printf("%d\n",ans);
return 0;
}
【BZOJ1717】产奶的模式(后缀数组)的更多相关文章
- 【BZOJ-1717】Milk Patterns产奶的模式 后缀数组
1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 881 Solved: ...
- BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]
1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1017 Solved: ...
- 【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组
[BZOJ1717][Usaco2006 Dec]Milk Patterns Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量 ...
- 【bzoj1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组+离散化
题目描述 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一 ...
- [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式——后缀数组
Brief Description 给定一个字符串,求至少出现k次的最长重复子串. Algorithm Design 先二分答案,然后将后缀分成若干组.判断有没有一个组的后缀个数不小于k.如果有,那么 ...
- bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分)
/* 求可重叠的至少重复K次的最长字串 以1为下标起点,因为a[i]最大到1000000,所以要先离散一下 二分长度len 然后O(n)检验 后看h[i]是否有连续的一段h[i]大于len的,并且h[ ...
- [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组_二分答案
Milk Patterns 产奶的模式 bzoj-1717 Usaco-2006 Dec 题目大意:给定一个字符串,求最长的至少出现了$k$次的子串长度. 注释:$1\le n\le 2\cdot 1 ...
- BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )
二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include&l ...
- BZOJ_1717_[Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组
BZOJ_1717_[Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他 ...
随机推荐
- 修改Request 中的数据
拦截器修改参数 今天一位网友开发中遇到一个需求,他需要在Request中修改传递过来的数据.开始的时候他在拦截器中修改,在拦截器中可以获取到从前台request中 传递过来的数据.他写法大致如下:自定 ...
- 2n皇后问题
此题为蓝桥杯基础练习题. 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后 ...
- mysql中的coalesce用法
在mysql中,其实有不少方法和函数是很有用的,这次介绍一个叫coalesce的,拼写十分麻烦,但其实作用是将返回传入的参数中第一个非null的值,比如 SELECT COALESCE(NULL ...
- 获取对象属性类型、属性名称、属性值的研究:反射和JEXL解析引擎
同步发布:http://www.yuanrengu.com/index.php/20170511.html 先简单介绍下反射的概念:java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所 ...
- java-redis初探
一.Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的 ...
- Python中List和Tuple类型
a = 'python' print('hello,', a or 'world') b = '' print ('hello,', b or 'world') print('------------ ...
- MySQL 参数- Innodb_File_Per_Table(独立表空间)
Innodb存储引擎可将所有数据存放于ibdata*的共享表空间,也可将每张表存放于独立的.ibd文件的独立表空间.共享表空间以及独立表空间都是针对数据的存储方式而言的. 共享表空间某一个数据库的所有 ...
- Linux服务器上安装MySql数据库(默认安装,密码为空),首次使用需要修改密码
1,在/etc/my.cnf末尾 加入skip-grant-tables,保存,跳过身份验证. 2,重启MySql,使刚才修改的配置生效. 3,终端输入mysql,然后再输入use mysql; 4 ...
- C语言_scanf()和getchar() 使用[粗俗易懂]
原文地址:http://blog.csdn.net/hao5743/article/details/6939661/,以下是我重新整理的以下. 问题描述一:[分析scanf()和getchar()读取 ...
- window 环境变量保存位置在哪里?
注册表-regedit.exe 用户变量: HKEY_CURRENT_USER\Environment 系统变量: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSe ...