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. threadLocal遇上线程池导致局部变量变化

    这两天一直在查无线app一个诡异的问题,表象是stg的接口返回数据,和线上接口的返回数据不一致. 1.初步判断:有缓存,查看代码后发现缓存时间直邮6分钟,而且同一个接口,其他调用方的返回数据,stg和 ...

  2. COGS 2084. Asm.Def的基本算法

    ★☆   输入文件:asm_algo.in   输出文件:asm_algo.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] “有句美国俗语说,如果走起来像鸭子,叫起来像 ...

  3. 洛谷P1628 合并序列

    题目描述 有N个单词和字符串T,按字典序输出以字符串T为前缀的所有单词. 输入输出格式 输入格式: 输入文件第一行包含一个正整数N: 接下来N行,每行一个单词,长度不超过100: 最后一行包含字符串T ...

  4. python hdfs初体验

    新建目录 chr 新建文件hdfstest1.txt并写入内容 复制hdfstest1.txt的内容到hdfstest2.txt

  5. WINDOWS-API:API函数大全

    操作系统除了协调应用程序的执行.内存分配.系统资源管理外,同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务是一个函数),可以帮肋应用程序达到开启视窗.描绘图形.使用周边设备的目的,由 ...

  6. BXS入门赛部分writeup

    pwn1  盲打(笑) 前言:没有听鱼哥的话,事先没有装好环境,于是开始没做出来,然后全程在装pwntools,经过一番努力,失败了0.0 最终在网上搜了一段python socket连接脚本,终于可 ...

  7. nodejs 设置安装包路径的取消和安装cnpm

    安装cnpm: $ npm install -g cnpm --registry=https://registry.npm.taobao.org 配置nodejs的npm安装包路径: npm conf ...

  8. [LUOGU] P1048 采药

    题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...

  9. Git学习——工作区和暂存区

    工作区就是我们的电脑上的git初始化目录.版本库就是我们工作区中的隐藏目录.git.版本库中分为两个部分:(1)stage(index)暂存区:git add <file>命令后file就 ...

  10. VS第一天(一堆错误的错误示范)

    自学VS第一天 (目标用vs做个不low的简历) 学习视频 https://www.bilibili.com/video/av48489320/?p=1 代码 写了一天的代码,自己理解的内容在注释里 ...