[bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)
以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= =
定义(来自关于后缀数组的那篇国家集训队论文。。)
后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列SA[1],SA[2],……,SA[n],并且保证Suffix(SA[i])<Suffix(SA[i+1]),1≤i<n。
也就是将S的n个后缀从小到大进行排序之后把排好序的后缀的开头位置顺次放入SA中。
height数组:定义height[i]=suffix(sa[i-1])和suffix(sa[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀。
接着是许昊然在《数据结构漫谈》中的讲解//原谅我不知道复制文字的正确技巧QAQ


听起来(而且事实上)的确挺简单的= =
最感人的是反正前面复杂度都已经O(n log²n)了。。。后面就随便玩了反正超时了也是前面的锅。。。
然而复杂度实在是有点虚。。。虽然本题n才2w,但是OJ上跑了600+ms。。。。。似乎还是数据随机的情况下
如果是较极限的数据(似乎没什么区别。。)的话10w的数据范围学校机子要跑3s。。。。
然后删掉取模,让它自然溢出的话似乎大概也许可能是在1s内跑出来的吧。。。。。。。。事实证明n=10w时要1.5s左右= =QAQ//学校机子1s内能循环2亿次= =
综上。。。我选择相信测评姬(捂脸
SA数组和height数组造出来后这题就是《后缀数组——处理字符串的有力工具》里面的例题了= =
诶好像有点详略不当
引用部分原文:
先二分答案为mid,把题目变成判定性问题。
解决这个问题的关键还是利用height数组。把排序后的后缀分成若干组,其中每组的后缀之间的height值都不小于mid(最长公共前缀长度不小于mid的两个后缀一定在同一组)。
判断有没有一个组的后缀个数不小于k即可。
傻逼代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=;
struct zs{
int pos;
}sa[maxn];
int s[maxn];
ll pre[maxn],modd,jc[maxn],val1,val2;
int l,r,mid,i,j,k,n,m,now,nowlen,K;
int h[maxn];
inline int getlen(int s1,int s2){//求两后缀(分别从s1,s2开始)的最长公共前缀的长度
if(s[s1]!=s[s2])return ;
int l=,r=n-max(s1,s2)+,mid;
while(l<r){
mid=(l+r+)>>;
val1=pre[s1+mid-]-pre[s1-]*jc[mid]%modd;
val2=pre[s2+mid-]-pre[s2-]*jc[mid]%modd;
if(val1<)val1+=modd;if(val2<)val2+=modd;
if(val1==val2)l=mid;else r=mid-;
}
return l;
}
inline bool bigger(int s1,int s2){
if(s[s1]!=s[s2])return s[s1]>s[s2];
int len=getlen(s1,s2);
if(len==n-max(s1,s2)+)
return s1<s2;
return s[s1+len]>s[s2+len];
}
bool cmp(zs a,zs b){
return !bigger(a.pos,b.pos);
}
int main(){
scanf("%d%d",&n,&K);
for(i=;i<=n;i++)scanf("%d",&s[i]);
modd=;
jc[]=;
for(i=;i<=n;i++)jc[i]=jc[i-]*%modd,pre[i]=(pre[i-]*%modd+s[i])%modd;/
for(i=;i<=n;i++)sa[i].pos=i;
sort(sa+,sa++n,cmp);
for(i=;i<=n;i++)h[i]=getlen(sa[i].pos,sa[i-].pos);
l=;r=n;
while(l<r){
mid=(l+r+)>>;
now=;nowlen=;
for(i=;i<=n+&&nowlen<K;i++)if(h[i]<mid)nowlen=max(nowlen,i-now),now=i;
if(nowlen<K)r=mid-;else l=mid;
}
printf("%d\n",l);
return ;
}

[bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)的更多相关文章
- bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式
后缀数组+二分答案+离散化.(上次写的时候看数据小没离散化然后一直WA...写了lsj师兄的写法. #include<cstdio> #include<cstring> #in ...
- [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组_二分答案
Milk Patterns 产奶的模式 bzoj-1717 Usaco-2006 Dec 题目大意:给定一个字符串,求最长的至少出现了$k$次的子串长度. 注释:$1\le n\le 2\cdot 1 ...
- bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分)
/* 求可重叠的至少重复K次的最长字串 以1为下标起点,因为a[i]最大到1000000,所以要先离散一下 二分长度len 然后O(n)检验 后看h[i]是否有连续的一段h[i]大于len的,并且h[ ...
- [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式——后缀数组
Brief Description 给定一个字符串,求至少出现k次的最长重复子串. Algorithm Design 先二分答案,然后将后缀分成若干组.判断有没有一个组的后缀个数不小于k.如果有,那么 ...
- BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]
1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1017 Solved: ...
- BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )
二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include&l ...
- BZOJ#1717:[Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+单调队列)
1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的 ...
- BZOJ_1717_[Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组
BZOJ_1717_[Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他 ...
- 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式
1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1469 Solved: ...
随机推荐
- C 真正理解二级指针
本文转载自CSDN博主liaoxinmeng,做数据结构时遇到指针方面的问题,想了许久,因此我觉得很有必要复习一下二级指针及其使用 正文如下: 指针是C语言的灵魂,我想对于一级指针大家应该都很熟悉,也 ...
- ABP .Net Core 部署到IIS 问题汇总
在ABP官网创建一个.Net Core项目编译完成 1. 发布网站 2. IIS新建站点 目录指向发布的目录 3.安装WindowsHosting IIS安装服务器上安装DotNetCore.X.X. ...
- A星寻路算法(A* Search Algorithm)
你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...
- MySQL MVCC机制
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/68 行结构 每一行额外包含三个隐藏字段: DB_TRX_ID:事 ...
- [Count the numbers satisfying (m + sum(m) + sum(sum(m))) equals to N]
Given an integer N, the task is to find out the count of numbers M that satisfy the condition M + su ...
- 算法分析| 小o和小ω符号
渐近分析的主要思想是对不依赖于机器特定常数的算法的效率进行测量,主要是因为该分析不需要实现算法并且要比较程序所花费的时间. 我们已经讨论了三个主要的渐近符号.本文我们使用以下2个渐近符号表示算法的时间 ...
- Swift学习第二天--面向对象
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- 豹哥嵌入式讲堂:ARM开发中有用的文件(1)- source文件
大家好,我是豹哥,猎豹的豹,犀利哥的哥.今天豹哥给大家讲的是嵌入式开发里的source文件种类. 众所周知,嵌入式开发属于偏底层的开发,主要编程语言是C和汇编.所以本文要讲的source文件主要指的就 ...
- HTML学习 表格和表单
<table></table> 表格标签 width 宽度 border 边框 cellpadding 内容和单元格之间的 ...
- Yarn篇--搭建yran集群
一.前述 有了上次hadoop集群的搭建,搭建yarn就简单多了.废话不多说,直接来 二.规划 三.配置如下 yarn-site.xml配置 <property> <n ...