问题描述

LG2852


题解

字符串性质:字符串\(s\)的每个字串等于每个后缀的所有前缀

对输入的东西离散化,然后把数值看做\(\mathrm{ASCII}\)后缀排序

二分答案,二分长度。

显然一段相同的字串,一定是连续一段后缀的公共前缀。

如此\(check\)即可。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std; #define maxn 20007 void read(int &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') fh=-1,ch=getchar();
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
} struct node{
int val,id,New;
}st[maxn]; int sa[maxn],n,m,ct[maxn],x[maxn],y[maxn],tot;
int hei[maxn];
int a[maxn],cnt,rk[maxn];
int low,l,r,mid,ans; bool comp(node a,node b){
return a.val<b.val;
} bool cmp(node a,node b){
return a.id<b.id;
} void preprocess(){
sort(st+1,st+n+1,comp);
for(register int i=1;i<=n;i++){
if(i==1||(i>1&&st[i].val>st[i-1].val)){
m++;
}
st[i].New=m;
}
sort(st+1,st+n+1,cmp);
for(register int i=1;i<=n;i++){
a[i]=st[i].New;
}
++m;
} void SA(){
for(register int i=1;i<=n;i++) ct[x[i]=a[i]]++;
for(register int i=2;i<=m;i++) ct[i]+=ct[i-1];
for(register int i=n;i>=1;i--) sa[ct[x[i]]--]=i;
for(register int k=1;k<=n;k<<=1){
int tot=0;
for(register int i=n-k+1;i<=n;i++) y[++tot]=i;
for(register int i=1;i<=n;i++) if(sa[i]>k) y[++tot]=sa[i]-k;
for(register int i=1;i<=m;i++) ct[i]=0;
for(register int i=1;i<=n;i++) ct[x[i]]++;
for(register int i=1;i<=m;i++) ct[i]+=ct[i-1];
for(register int i=n;i>=1;i--) sa[ct[x[y[i]]]--]=y[i],y[i]=0;
swap(x,y);x[sa[1]]=tot=1;
for(register int i=2;i<=n;i++)
if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]) x[sa[i]]=tot;
else x[sa[i]]=++tot;
if(tot==n) break;
m=tot;
}
} void HEIGHT(){
int tmp=0;
for(register int i=1;i<=n;i++) rk[sa[i]]=i;
for(register int i=1;i<=n;i++){
if(rk[i]==1) continue;
if(tmp) --tmp;
int j=sa[rk[i]-1];
while(j+tmp<=n&&i+tmp<=n&&a[i+tmp]==a[j+tmp]) ++tmp;
hei[rk[i]]=tmp;
}
} bool check(){
if(mid==0) return true;
int lst=0;
for(register int i=1;i<=n;i++){
if(hei[i]<mid){//错误笔记:将mid写为m,以后check写传参式的
if(i-lst>=low) return true;
lst=i;
}
}
if(n+1-lst>=low) return true;
return false;
} int main(){
read(n);read(low);
for(register int i=1;i<=n;i++){
read(st[i].val);st[i].id=i;
}
preprocess();
SA();HEIGHT();
l=0,r=n;
while(l<=r){
mid=(l+r)>>1;
if(check()) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}

LG2852/BZOJ1717 「USACO2006DEC」Milk Patterns 离散化+后缀数组的更多相关文章

  1. POJ 3261 Milk Patterns(后缀数组+二分答案+离散化)

    题意:给定一个字符串,求至少出现k 次的最长重复子串,这k 个子串可以重叠. 分析:经典的后缀数组求解题:先二分答案,然后将后缀分成若干组.这里要判断的是有没有一个组的符合要求的后缀个数(height ...

  2. poj 3261 Milk Patterns(后缀数组)(k次的最长重复子串)

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7938   Accepted: 3598 Cas ...

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

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

  4. POJ 3261 Milk Patterns (后缀数组,求可重叠的k次最长重复子串)

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16742   Accepted: 7390 Ca ...

  5. liberOJ #2033. 「SDOI2016」生成魔咒 后缀数组

    #2033. 「SDOI2016」生成魔咒     题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 11.2 22 拼凑起来形成一个魔咒串 [1,2] [1, 2] ...

  6. 【BZOJ1717&POJ3261】Milk Patterns(后缀数组,二分)

    题意:求字符串的可重叠的k次最长重复子串 n<=20000 a[i]<=1000000 思路:后缀数组+二分答案x,根据height分组,每组之间的height>=x 因为可以重叠, ...

  7. poj3261 Milk Patterns【后缀数组】【二分】

    Farmer John has noticed that the quality of milk given by his cows varies from day to day. On furthe ...

  8. POJ-3261 Milk Patterns(后缀数组)

    题目大意:找出至少出现K次的子串的最长长度. 题目分析:二分枚举长度x,判断有没有最长公共前缀不小于x的并且连续出现了至少k次的有序子串区间. 代码如下: # include<iostream& ...

  9. poj3261 Milk Patterns(后缀数组)

    [题目链接] http://poj.org/problem?id=3261 [题意] 至少出现k次的可重叠最长子串. [思路] 二分长度+划分height,然后判断是否存在一组的数目不小于k即可. 需 ...

随机推荐

  1. 简化wcf的service设置

    使用wcf作为c/s的通信桥梁,就免不了要写wcf service,更免不了写一些配置. 但是在把系统中所有的.net remoting service都转换成wcf service以后,发现居然有2 ...

  2. 【CometOJ】Comet OJ - Contest #8 解题报告

    点此进入比赛 \(A\):杀手皇后(点此看题面) 大致题意: 求字典序最小的字符串. 一场比赛总有送分题... #include<bits/stdc++.h> #define Tp tem ...

  3. 第02组 Beta冲刺(1/5)

    队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 初步任务分配 提交记录(全组共用) 接下来的计划 完善接口文档 还剩下哪些任务 学习软工的理论课 学习代码评估.测试 燃尽 ...

  4. RocketMQ的顺序消费和事务消费

    一.三种消费 :1.普通消费 2. 顺序消费 3.事务消费 1.1  顺序消费:在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成.也就是这个三个 ...

  5. Spring源码系列 — 注解原理

    前言 前文中主要介绍了Spring中处理BeanDefinition的扩展点,其中着重介绍BeanDefinitionParser方式的扩展.本篇文章承接该内容,详解Spring中如何利用BeanDe ...

  6. 【09】Nginx:静态压缩 / 日志切割 / 防盗链 /恶意解析/ 跨域

    写在前面的话 上一节我们谈了关于 nginx 服务器的一些简单的安全优化问题,能够帮助我们解决一部分线上服务存在的安全隐患.但是想要提升用户体验这是原因不够的,我们还需要从服务的优化方面入手. 本节更 ...

  7. 如何通过 Freemark 优雅地生成那些花里胡哨的复杂样式 Excel 文件?

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  8. js变量类型及检查

    一.变量的类型 JavaScript 有六种数据类型.主要的类型有 Number.String.object 以及 Boolean 类型,其他两种类型为 null 和 undefined.var ob ...

  9. mac中使用expect脚本,让iTerms保存密码登录ssh

    最近工作中需要使用ssh连接到centos服务器中,以前公司都是直接配的私钥就可以免密登录了.这里还用的密码. 由于,我一直用的是iTerm2,所以在网上搜索了下,找到了一种方案,那就是expect脚 ...

  10. mssql like 优化

    SqlServer中like 的查询一般我们都不推荐,但是当数据库某个字段的值是用分隔符区分的多个链接字符,比如,12,11,23等这样的类型.可能我们需要判断是否包含12. 这个时候我们想到的当然是 ...