题目大意:求可重叠的相同子串数量至少是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 (后缀数组+二分)的更多相关文章

  1. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  2. POJ-3261 Milk Patterns,后缀数组+二分。。

                                                        Milk Patterns 题意:求可重叠的至少重复出现k次的最长的字串长. 这题的做法和上一题 ...

  3. poj 3261 Milk Patterns 后缀数组 + 二分

    题目链接 题目描述 给定一个字符串,求至少出现 \(k\) 次的最长重复子串,这 \(k\) 个子串可以重叠. 思路 二分 子串长度,据其将 \(h\) 数组 分组,判断是否存在一组其大小 \(\ge ...

  4. BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )

    二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...

  5. [USACO06FEC]Milk Patterns --- 后缀数组

    [USACO06FEC]Milk Patterns 题目描述: Farmer John has noticed that the quality of milk given by his cows v ...

  6. 【题解】回文串 APIO 2014 BZOJ 3676 COGS 1985 Manacher+后缀数组+二分

    这题可以用回文自动机来做,但是我并没有学,于是用Manacher+SA的做法O(nlogn)水过 首先,看到回文串就能想到用Manacher 同样还是要利用Manacher能不重复不遗漏地枚举每个回文 ...

  7. 【poj 3261】Milk Patterns 后缀数组

    Milk Patterns 题意 给出n个数字,以及一个k,求至少出现k次的最长子序列的长度 思路 和poj 1743思路差不多,二分长度,把后缀分成若干组,每组任意后缀公共前缀都>=当前二分的 ...

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

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

  9. poj3261 Milk Patterns 后缀数组求可重叠的k次最长重复子串

    题目链接:http://poj.org/problem?id=3261 思路: 后缀数组的很好的一道入门题目 先利用模板求出sa数组和height数组 然后二分答案(即对于可能出现的重复长度进行二分) ...

随机推荐

  1. php多维数组的指定单个字段排序

    多维数组如何根据指定键值?比如现在有数组结构如下: ,,,,,'subject' => 'math'), 1 => array('name' => '3班','avgScore'=& ...

  2. Webpack 学习记录之概念

    1 什么是webpack webpack是一个模块打包器,可以递归的构建一个依赖关系图,其中包含每个程序需要的每个模块,然后将所有模块打包成一个或多个bundle.他和其他的工具最大的不同在于他支持c ...

  3. JavaScript:进制转换。

    最近做了一些进制的转换的点. 十进制转二进制: let a = 45; a.toString(2); //"101101" let b = 123; b.toString(2); ...

  4. UVA227 - Puzzle(紫书习题3.5)

    #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring&g ...

  5. tf.truncated_normal和tf.random_normal使用方法的区别

    1.tf.truncated_normal使用方法 tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=No ...

  6. hadoop的理解

    知乎上有个人写的感觉挺好理解的,不知道对不对,先截图存着

  7. 关于java发送email

    转载:https://blog.csdn.net/qq_32371887/article/details/72821291 1:使用JavaMail发送邮件 // 1.创建一个程序与邮件服务器会话对象 ...

  8. HDU2188(巴什博奕)

    悼念512汶川大地震遇难同胞--选拔志愿者 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...

  9. eclipse转Android studio遇到的那些坑

           公司项目有导入10多个libray,还有涉及ndk,转Android studio时碰到不少问题.前后大概花费5个工作日,中间各种奇葩bug,各种编译出错,非常多还有没错误提示.一度想过 ...

  10. js面向对象编程:怎样实现方法重载

    js中怎样实现方法重载?这涉及到三个问题 1同名函数的调用问题 2函数中特殊的參数arguments 3怎样利用arguments实现方法重载 1同名函数的调用问题 都知道在js中假设存在多个名称同样 ...