BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)
题目大意:求可重叠的相同子串数量至少是K的子串最长长度
依然是后缀数组+二分,先用后缀数组处理出height
每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个串的长度>=x,
但据说有一种高端做法是把二分换成单调队列,能减少常数,可惜我并没有看懂......
原题好像是哈希的骚操作,但网上的题解好像都是后缀数组......
比上一道男人八题简单多了,我原来的错代码竟然卡过去了70分..
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 20010
#define inf 0x3f3f3f3f
#define maxn 1000010
using namespace std; int n,len,tot,K;
int a[N],tr[N],sa[N],rk[N],hs[N],h[N];
struct node{int id,val,w;}d[N];
int cmp1(node s1,node s2){return s1.val<s2.val;}
int cmp2(node s1,node s2){return s1.id<s2.id;}
int gint()
{
int rett=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){rett=(rett<<)+(rett<<)+c-'';c=getchar();}
return rett*fh;
}
bool check(int k,int x,int y){
if(x+k>len||y+k>len) return ;
else return (rk[x]==rk[y]&&rk[x+k]==rk[y+k])?:;
}
void get_sa()
{
int cnt=,i;
for(i=;i<=len;i++) hs[a[i]]++;
for(i=;i<=tot;i++) if(hs[i]) tr[i]=++cnt;
for(i=;i<=tot;i++) hs[i]+=hs[i-];
for(i=;i<=len;i++) rk[i]=tr[a[i]],sa[hs[a[i]]--]=i;
for(int k=;cnt<len;k<<=)
{
for(i=;i<=cnt;i++) hs[i]=;
for(i=;i<=len;i++) hs[rk[i]]++;
for(i=;i<=cnt;i++) hs[i]+=hs[i-];
for(i=len;i>=;i--) if(sa[i]>k) tr[sa[i]-k]=hs[rk[sa[i]-k]]--;
for(i=;i<=k;i++) tr[len-i+]=hs[rk[len-i+]]--;
for(i=;i<=len;i++) sa[tr[i]]=i;
for(i=,cnt=;i<=len;i++) tr[sa[i]]=check(k,sa[i],sa[i-])?cnt:++cnt;
for(i=;i<=len;i++) rk[i]=tr[i];
}
}
void get_height()
{
for(int i=;i<=n;i++){
if(rk[i]==) continue;
for(int j=max(,h[rk[i-]]-);;j++)
if(a[i+j-]==a[sa[rk[i]-]+j-]) h[rk[i]]=j;
else break;
}
}
void descrete()
{
sort(d+,d+n+,cmp1);
d[].val=-;
for(int i=;i<=n;i++)
if(d[i].val==d[i-].val)
d[i].w=d[i-].w;
else d[i].w=++tot;
sort(d+,d+n+,cmp2);
for(int i=;i<=n;i++)
a[i]=d[i].w;
}
int check(int ans)
{
int i,cnt=;
for(i=;i<=n;)
{
if(h[i]<ans) {i++;continue;}
for(cnt=;h[i]>=ans&&i<=n;i++)
cnt++;
if(cnt>=K-) return ;
}return ;
} int main()
{
scanf("%d%d",&n,&K);len=n;
for(int i=;i<=n;i++)
d[i].val=gint(),d[i].id=i;
descrete();
get_sa();
get_height();
int l=,r=n,ans=;
while(l<=r){
int mid=(l+r)>>;
if(check(mid)) ans=mid,l=mid+;
else r=mid-;
}printf("%d\n",ans);
return ;
}
BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)的更多相关文章
- Poj 3261 Milk Patterns(后缀数组+二分答案)
Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...
- POJ-3261 Milk Patterns,后缀数组+二分。。
Milk Patterns 题意:求可重叠的至少重复出现k次的最长的字串长. 这题的做法和上一题 ...
- poj 3261 Milk Patterns 后缀数组 + 二分
题目链接 题目描述 给定一个字符串,求至少出现 \(k\) 次的最长重复子串,这 \(k\) 个子串可以重叠. 思路 二分 子串长度,据其将 \(h\) 数组 分组,判断是否存在一组其大小 \(\ge ...
- BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )
二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...
- [USACO06FEC]Milk Patterns --- 后缀数组
[USACO06FEC]Milk Patterns 题目描述: Farmer John has noticed that the quality of milk given by his cows v ...
- 【题解】回文串 APIO 2014 BZOJ 3676 COGS 1985 Manacher+后缀数组+二分
这题可以用回文自动机来做,但是我并没有学,于是用Manacher+SA的做法O(nlogn)水过 首先,看到回文串就能想到用Manacher 同样还是要利用Manacher能不重复不遗漏地枚举每个回文 ...
- 【poj 3261】Milk Patterns 后缀数组
Milk Patterns 题意 给出n个数字,以及一个k,求至少出现k次的最长子序列的长度 思路 和poj 1743思路差不多,二分长度,把后缀分成若干组,每组任意后缀公共前缀都>=当前二分的 ...
- POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次
Milk Patterns Description Farmer John has noticed that the quality of milk given by his cows varie ...
- poj3261 Milk Patterns 后缀数组求可重叠的k次最长重复子串
题目链接:http://poj.org/problem?id=3261 思路: 后缀数组的很好的一道入门题目 先利用模板求出sa数组和height数组 然后二分答案(即对于可能出现的重复长度进行二分) ...
随机推荐
- 漫谈 Google 的 Native Client(NaCl) 技术(二)---- 技术篇(兼谈 LLVM)
转自:http://hzx5.blog.163.com/blog/static/40744388201172531637729/ 漫谈 Google 的 Native Client(NaCl) 技术( ...
- java:递归算法
JAVA中的递归是只一个方法在(满足条件时(或不满足条件时[这里的判断根据业务的实际需求写]))自己调用自己的方法名,要求参数和方法名一致, 然后根据判断跳出该方法,返回相应的返回值! 实例: 我们要 ...
- Trie树检索字符串
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct TrieNode ...
- echarts在vue里面使用,以及基础配置。
基础的图表和基础的配置. 效果图如下: 1.安装图表依赖包:npm install echarts 2.在main.js里面 引入echarts import echarts from 'echart ...
- 最大团&稳定婚姻系列
[HDU] 1530 Maximum Clique 1435 Stable Match 3585 maximum shortest distance 二分+最大团 1522 Marriage is ...
- BigInteger类(高精度整型)
位置:java.math.BigInteger 作用:提供高精度整型数据类型及相关操作 一.基本介绍 BigInteger为不可变的任意精度的整数(对象创建后无法改变,每次运算均会产生一个新的对象). ...
- linux下添加自定义脚本到开机自启动的方法
原文链接:http://www.jb51.net/LINUXjishu/183462.html 我的机器有个coreseek服务,但是没加到开启启动中去,导致机房一旦重启了机器,我的服务便不能使用了. ...
- iterator遍历list理解
1.iterator的next()方法返回值,就是你指定的iiterator<>泛型.所以你再强制转换,就可以得到list里的item了,直接是item对象了. 2.list这东西,你ne ...
- Shell编程入门(第二版)(上)
简单的示例Shell程序 示例1. #!/bin/bash #This is to show what a shell script looks like echo "Our first e ...
- lpa标签传播算法解说及代码实现
package lpa; import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class L ...