Milk Patterns

题意:求可重叠的至少重复出现k次的最长的字串长。

这题的做法和上一题差不多,也是先二分答案,然后将后缀分成若干组。不同的是,这里要判断的是有没有一个组的后缀个数不小于k。如果有,那么存在k个相同的子串满足条件,否则不存在。这个做法的时间复杂度为 O(nlogn)。

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<functional>
//#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define pd(x) printf("%d\n",x)
//#define plld(x) printf("%lld\n",x)
//#define pI64d(x) printf("%I64d\n",x)
const int INF=1e9;
const int MOD=1e9+7;
const int N=1e6+5;
const double eps=1e-4;
const double PI=acos(-1.0);
int Rank[N],height[N];
int a[N],sa[N],t[N],t1[N],c[N],n,cnt,m=N;
void build(int n)
{
int i,*x=t,*y=t1;
memset(c,0,sizeof(c));
for(i=0;i<n;i++) c[x[i]=a[i]]++;
for(i=1;i<m;i++) c[i]+=c[i-1];
for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1)
{
int p=0;
for(i=n-k;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
memset(c,0,sizeof(c));
for(i=0;i<n;i++) c[x[y[i]]]++;
for(i=1;i<m;i++) c[i]+=c[i-1];
for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1,x[sa[0]]=0;
for(i=1;i<n;i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n) break;
m=p;
}
// for(i=0;i<n;i++) printf("%d ",sa[i]);
// puts("");
}
void get_height()
{
int k=0;
for(int i=1;i<=n;i++) Rank[sa[i]]=i;
for(int i=0;i<n;i++)
{
if(k) k--;
int j=sa[Rank[i]-1];
while(a[i+k]==a[j+k]) k++;
height[Rank[i]]=k;
}
}
int find(int k)
{
int i=1;
while(i<=n)
{
while(i<=n&&height[i]<k) i++;
int num=1;
while(i<=n&&height[i]>=k) i++,num++;
if(num>=cnt) return 1;
}
return 0;
}
void show()
{
puts("");
for(int i=0;i<=n;i++) printf("%d ",i);
puts("");
for(int i=0;i<=n;i++) printf("%d ",a[i]);
printf("\nsa:\n");
for(int i=0;i<=n;i++) printf("%d ",sa[i]);
printf("\nRank:\n");
for(int i=0;i<=n;i++) printf("%d ",Rank[i]);
printf("\nHight:\n");
for(int i=0;i<=n;i++) printf("%d ",height[i]);
puts(""); }
int main()
{
while(~scanf("%d%d",&n,&cnt))
{
for(int i=0;i<n;i++) scanf("%d",&a[i]);
a[n]=0;
build(n+1);
get_height();
// show();
int l=0,r=n;
while(l<r)
{
int mid=(l+r+1)/2;
if(find(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
}
return 0;
}

唉,写下来100行妥妥的, debug比写代码累多了。。感觉对这些知识点的理解度不够,只会模板。

最新文章

  1. python,django安装
  2. Javaweb学习笔记——EL表达式
  3. JavaScript - BOM
  4. Oracle中用户的基本操作
  5. B:冷血格斗场
  6. 淘宝开放平台TOP测试环境
  7. Hibernate+Struts2+jsp 修改用户信息
  8. 数据库索引B+树
  9. [Python] UTF-8最好不要带BOM
  10. Android Studio工程导入另一个工程作为lib
  11. 基于Bootstrap实现下图所示效果的页面,一个白底的带有两个菜单项、一个下拉菜单和一个登录表单的基本导航条
  12. util.go
  13. JS直接if参数的用法
  14. Mongodb----整理
  15. spring @Order标记
  16. 报错500 DEFAULT_INCOMPATIBLE_IMPROVEMENTS
  17. UNIX环境编程学习笔记(26)——多线程编程(一):创建和终止线程
  18. BZOJ5131: [CodePlus2017年12月]可做题2
  19. HUE配置文件hue.ini 的hdfs_clusters模块详解(图文详解)(分HA集群和非HA集群)
  20. vuejs code splitting with webpack 3种模式

热门文章

  1. 单线程异步回调机制的缺陷与node的解决方案
  2. 安装ubuntu虚拟环境
  3. HTML5+CSS3新增内容总结!!!!!绝对干货
  4. IE兼容rgba()透明度
  5. 修改输入框placeholder的默认样式
  6. Linux下的I/O复用
  7. SnowKiting
  8. 洛谷 P1363 幻想迷宫
  9. Codeforces Round #318 (Div. 2) A Bear and Elections (优先队列模拟,水题)
  10. python小括号( )与中括号 [ ]