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比写代码累多了。。感觉对这些知识点的理解度不够,只会模板。

POJ-3261 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 后缀数组 + 二分

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

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

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

  4. POJ 3261 Milk Patterns(后缀数组+单调队列)

    题意 找出出现k次的可重叠的最长子串的长度 题解 用后缀数组. 然后求出heigth数组. 跑单调队列就行了.找出每k个数中最小的数的最大值.就是个滑动窗口啊 (不知道为什么有人写二分,其实写啥都差不 ...

  5. POJ 3261 Milk Patterns ( 后缀数组 && 出现k次最长可重叠子串长度 )

    题意 : 给出一个长度为 N 的序列,再给出一个 K 要求求出出现了至少 K 次的最长可重叠子串的长度 分析 : 后缀数组套路题,思路是二分长度再对于每一个长度进行判断,判断过程就是对于 Height ...

  6. BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)

    题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...

  7. POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)+后缀数组模板

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7586   Accepted: 3448 Cas ...

  8. POJ 3261 Milk Patterns 【后缀数组 最长可重叠子串】

    题目题目:http://poj.org/problem?id=3261 Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Subm ...

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

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

随机推荐

  1. Python 学习日志9月18日

    今天早晨学习了<Head First HTML and CSS>,第10章“div and span”. 看完并且做了练习也算是对div和span扫了个盲,需要在实践练习中加强理解与掌握. ...

  2. 融云参加RTC实时互联网大会 现场集成IM SDK

    9月21至22日,由全球实时云服务商声网Agora.io主办的RTC2017实时互联网大会在北京万豪酒店成功举办.作为亚洲最权威的RTC实时通信行业技术盛会,会议吸引了来自全球上千名开发者参加,Goo ...

  3. OpenGL 渲染上下文-context

    context理解 OpenGL在渲染的时候需要一个Context,这个Context记录了OpenGL渲染需要的所有信息,可以把它理解成一个大的结构体,它里面记录了当前绘制使用的颜色.是否有光照计算 ...

  4. mongo ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused

    解决方法 rm /var/lib/mongodb/mongod.lock

  5. SQLite-表达式

    SQLite -表达式 一个表达式是一个或多个值的组合,运算符和SQL函数,评价一个值. SQL表达式就像公式和都写在查询语言.您还可以使用为特定的数据集查询数据库. 语法: 考虑到SELECT语句的 ...

  6. 分布式锁----浅析redis实现

    引言大概两个月前小伙伴问我有没有基于redis实现过分布式锁,之前看redis的时候知道有一个RedLock算法可以实现分布式锁,我接触的分布式项目要么是github上开源学习的,要么是小伙伴们公司项 ...

  7. js 两个数组对象根据账号比较去重,解决直接splice后数组索引改变

    目的获取Arr2中不包含在arr1中的对象 根据Account进行比较,如果相等则删除tempArr数组对象. 结果返回张三 var arr1=[{"account":" ...

  8. iOS 优秀博客

    中文 iOS/Mac 开发博客列表 GitHub 上排名前 100 的 Objective-C 项目简介 GitHub 上都有哪些值得关注学习的 iOS 开源项目? iOS开发系列文章(持续更新……) ...

  9. UVa-227-谜题

    这题的话,我们读入的时候,可以用scanf单个读入字符,也可以用getchar函数来读入. scanf scanf读入串字符的时候,遇到空格.回车和TAB等空白字符就会停止读入,但是如果读入单个字符就 ...

  10. [LUOGU] 2820 局域网

    题目背景 某个局域网内有n(n<=100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象.因为连 ...