后缀数组练习2:可重叠的k次最长重复子串
其实和上一题是差不多的,只是在二分check的时候有一些小小的改动
1468: 后缀数组2:可重叠的k次最长重复子串
时间限制: 1 Sec 内存限制: 128 MB
提交: 113 解决: 48
[提交] [状态] [讨论版] [命题人:admin]题目描述
【问题描述】
农夫John发现他的奶牛产奶的质量一直在变动。经过细致的调查,他发现:虽然他不能预见明天 产奶的质量,但连续的若干天的质量有很多重叠。我们称之为一个“模式”。 John的牛奶按质量可以被赋予一个0到1000000之间的数。并且John记录了N(1<=N<=20000)天的 牛奶质量值。他想知道最长的出现了至少K(2<=K<=N)次的模式的长度。 比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次。当K=2时,这个长度为4。(可重叠的k次最长重复子串)
【输入格式】
* Line 1: 两个整数 N,K。
* Lines 2..N+1: 每行一个整数表示当天的质量值。
(多组数据)
【输出格式】
* Line 1: 一个整数:N天中最长的出现了至少K次的模式的长度
【样例】
输入:8 2
1
2
3
2
3
2
3
1
输出:4
/*后将后缀分成若干组。 不同的是,这里要判断的是有没有一个组的后缀个数不小于 k。
如果有,那么存在k 个相同的子串满足条件,否则不存在*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int sa[],Rank[],rsort[];
int a[],cnt[],pos[],height[];
bool cmp(int x,int y,int k){return cnt[x]==cnt[y] && cnt[x+k]==cnt[y+k];}
void get_sa(int n,int m)
{
int k=,p=,len;
for(int i=;i<=n;i++) Rank[i]=a[i];
memset(rsort,,sizeof(rsort));
for(int i=;i<=n;i++) rsort[Rank[i]]++;
for(int i=;i<=m;i++) rsort[i]+=rsort[i-];
for(int i=n;i>=;i--) sa[rsort[Rank[i]]--]=i;
for(int k=;k<n;k<<=)
{
len=;
for(int i=n-k+;i<=n;i++) pos[++len]=i;
for(int i=;i<=n;i++) if(sa[i]>k) pos[++len]=sa[i]-k;
for(int i=;i<=n;i++) cnt[i]=Rank[pos[i]];
memset(rsort,,sizeof(rsort));
for(int i=;i<=n;i++) rsort[cnt[i]]++;
for(int i=;i<=m;i++) rsort[i]+=rsort[i-];
for(int i=n;i>=;i--) sa[rsort[cnt[i]]--]=pos[i];
for(int i=;i<=n;i++) cnt[i]=Rank[i];
p=; Rank[sa[]]=;
for(int i=;i<=n;i++)
{
if(!cmp(sa[i],sa[i-],k)) p++;
Rank[sa[i]]=p;
}
if(p==n) break; m=p;
}
a[]=; sa[]=;
}
void get_he(int n)
{
int j,k=;
for(int i=;i<=n;i++)
{
j=sa[Rank[i]-];
if(k) k--;
while(a[j+k]==a[i+k]) k++;
height[Rank[i]]=k;
}
}
bool check(int mid,int n,int k)
{
int sum=;
for(int i=;i<=n;i++)
{
if(height[i]>=mid)/*满足条件*/
{
sum++;/*个数增加*/
if(sum==k) return true;/*如果满足条件就直接返回*/
}
else sum=;/*否则重新找*/
}
return false;
}
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(int i=;i<=n;i++) scanf("%d",&a[i]);
get_sa(n,); get_he(n);
int l=,r=n,ans=;
while(l<=r)
{
int mid=(l+r)/;
if(check(mid,n,k))
{
ans=mid;
l=mid+;
}
else r=mid-;
}
printf("%d\n",ans);
}
return ;
}
Tristan Code
后缀数组练习2:可重叠的k次最长重复子串的更多相关文章
- POJ 3261 Milk Patterns (后缀数组,求可重叠的k次最长重复子串)
Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 16742 Accepted: 7390 Ca ...
- POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)+后缀数组模板
Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7586 Accepted: 3448 Cas ...
- poj 3261 后缀数组 可重叠的 k 次最长重复子串
Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 16430 Accepted: 7252 Ca ...
- poj 3261 求可重叠的k次最长重复子串
题意:求可重叠的k次最长重复子串的长度 链接:点我 和poj1743差不多 #include<cstdio> #include<iostream> #include<al ...
- 【POJ 3261】Milk Patterns 可重叠的k次最长重复子串
可重叠的k次最长重复子串 #include<cstdio> #include<cstring> #include<algorithm> using namespac ...
- POJ 3261 可重叠的 k 次最长重复子串【后缀数组】
这也是一道例题 给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠.算法分析:这题的做法和上一题差不多,也是先二分答案,然后将后缀分成若干组.不同的是,这里要判断的是有没有一个组 ...
- poj3261 Milk Patterns 后缀数组求可重叠的k次最长重复子串
题目链接:http://poj.org/problem?id=3261 思路: 后缀数组的很好的一道入门题目 先利用模板求出sa数组和height数组 然后二分答案(即对于可能出现的重复长度进行二分) ...
- [Poj3261] [Bzoj1717] [后缀数组论文例题,USACO 2006 December Gold] Milk Patterns [后缀数组可重叠的k次最长重复子串]
和上一题(POJ1743,上一篇博客)相似,只是二分的判断条件是:是否存在一段后缀的个数不小于k #include <iostream> #include <algorithm> ...
- 后缀数组--可重叠的K次最长重复子串(POJ3261)
题目:Milk Patterns #include <stdio.h> #include <string.h> #define N 1000010 int wa[N],wb[N ...
随机推荐
- 一个轻量级的模态组件,“礼貌地”要求您的用户停止使用过时的IE浏览器
插件github地址:https://github.com/panteng/ie-blocker 我们在做项目时,会考虑到浏览器的兼容问题,当然做,全浏览器都支持的项目我还没经历过,也不想经历,目前做 ...
- Win10+ Clion + 树莓派 + QT进行远程qt程序开发
环境配置 环境配置 Windows上:QT5 + CLion 硬件上:一只可联网.可ssh连接且装有QT5的树莓派 暂时还没想好... 树莓派安装qt sudo apt-get update sudo ...
- Linux+CLion+树莓派远程编译时,Cmake编译出现undefined reference to 'dlopen'的解决办法
在Clion中链接讯飞的语音库并传至树莓派上编译时,出现如下错误. undefined reference to `dlopen' undefined reference to `dlclose' u ...
- IDEA2019.1.3的安装和破解
上一篇文章我有写过我会尝试安装IDEA(这玩意儿收费啊!),倘若尝试成功以后都会用它编译,很幸运,我安装成功了,所以今天这篇文章我来写安装和破解方法. IDEA界面: 首先我们访问官方网站:htt ...
- CF258B
CF258B 题意: 7个人在 $ [1,m] $ 区间内取数,求第一个人选的数的4和7的个数大于其他人的4和7个数总和的方案数. 解法: 要求输入的 $ m $ 可以很大,而且需要按位考虑每隔人的贡 ...
- Leetcode题目104.二叉树的最大深度(DFS+BFS简单)
题目描述: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null, ...
- 终端和vim中文编码问题
一. 终端中文显示乱码 有网友说修改 /var/lib/locales/supported.d/locale 和 /etc/default/locale 就可以了但是如果多人共用一台机器没有root权 ...
- SDN上机第4次作业
1. 解压安装OpenDayLight控制器(本次实验统一使用Beryllium版本) 1)JDK的安装与环境配置 嗯,装这个东西还得先装JDK: 在线真人手把手教你安装jdk 输入sud ...
- 本地服务CURL请求本地另一个服务API返回超时/或无返回
入职之后一直在忙,终于有时间整理一波最近踩到的坑. 起因: 项目是微服务架构,一个项目对外提供API,新的项目调用API获得数据.于是就在本地搭建了两个服务.配置了两个虚拟域名,指向两个项目,当然我本 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_6-01 微服务网关介绍和使用场景
笔记 第六章 微服务网关zuul开发实战 1.微服务网关介绍和使用场景 简介:讲解网关的作用和使用场景 (画图) 1)什么是网关 API Gateway,是系 ...