题意就是给一列数字,求最长的一个子串,并且满足子串在原数串中出现至少K次,子串可以重叠。

解法是将问题转为判定性问题,二分子串的长度,判定是否满足重复至少K次。判定方法是经典的根据子串长度将Height数组分组,看某一分组是否至少含有K个元素。

 1 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <cassert>
#include <sstream>
using namespace std; const int N=2e6+; int sa[N];
int t1[N],t2[N],c[N];
int rk[N],height[N]; inline int cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
int s[N];
void calcSA (int *s,int n,int m) {
int i,j,p,*x=t1,*y=t2;
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(j=;j<=n;j<<=){
p=;
for(i=n-j;i<n;i++)y[p++]=i;
for(i=;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; // 排名从小到大,如果pos比j大,则suffix(sa[i]-j)的第二关键字为p
for(i=;i<m;i++)c[i]=;
for(i=;i<n;i++)c[x[y[i]]]++;
for(i=;i<m;i++)c[i]+=c[i-];
for(i=n-;i>=;i--)sa[--c[x[y[i]]]]=y[i]; // 根据第二关键字从大到小,确定新一轮sa
swap(x,y);
p=;x[sa[]]=;
for(i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
if(p>=n)break;
m=p;
}
} void calcHeight(int *s,int n) {
int i,j,k=;
for(i=;i<=n;i++)rk[sa[i]]=i;
for(i=;i<n;i++){
if(k)k--; // h[i]>=h[i-1]-1
j=sa[rk[i]-]; // suffix(j)排名在suffix(i)前一位
while(s[i+k]==s[j+k])k++; // 暴力计算lcp
height[rk[i]]=k;
}
} bool ok(int n,int m,int k) {
int cnt=;
for (int i=;i<=n;i++) {
if (height[i]<m) {
cnt=;
}
else {
cnt++;
if (cnt>=k) return true;
}
}
return false;
}
int main () {
int n,k;
while (scanf("%d %d",&n,&k)!=EOF) {
int mx=;
for (int i=;i<n;i++) {
scanf("%d",s+i);
mx=max(mx,s[i]);
}
s[n]=;
calcSA(s,n+,mx+);
calcHeight(s,n);
int l=,r=n,ret=;
while (l<=r) {
int m=(l+r)>>;
if (ok(n,m,k)) {
ret=m;
l=m+;
}
else r=m-;
}
cout<<ret<<endl;
}
return ;
}

最新文章

  1. C标准头文件&lt;math.h&gt;
  2. 移动端App广告常见的10种形式
  3. 升级Xcode8控制台打印出来这些东西
  4. Increasing Triplet Subsequence
  5. Windows 下, SetTimer 定时器的研究.
  6. 【python游戏编程之旅】第五篇---嗷大喵爱吃鱼小游戏开发实例
  7. JPA的Column注解总结
  8. 34 个使用 Raspberry Pi 的酷创意
  9. call &amp;&amp; jmp 指令
  10. struts2 标签库 介绍
  11. fiddler使用之坑
  12. 微信应用号开发知识贮备之Webpack实战
  13. Core Animation之多种动画效果
  14. co源码解析
  15. 》》3D轮播
  16. c语言_FILE结构体解释及相关操作
  17. 在CentOS下安装crontab服务
  18. trigger回调方法的实现
  19. 二十三、Hadoop学记笔记————Spark简介与计算模型
  20. JS的常用正则表达式 验证密码(转载自用)

热门文章

  1. move.js 源码 学习笔记
  2. File类和时间类的两道综合练习
  3. maven 的 snapshot 和 release 的区别
  4. javascript继承--原型链的 继承
  5. 浅谈HashMap的内部实现
  6. Android开发之Notification的简单使用
  7. Babel指南——基本环境搭建
  8. 当在浏览器地址栏里输入URL后会发生什么事情
  9. ng自定义服务(利用factory)
  10. MySQL(Navicat)运行.sql文件时报错[Err] 2006 - MySQL server has gone away 的解决方法