问题描述

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. 首次使用gradle出现Could not find method leftShift() for arguments解决办法

    1.在win10桌面编写test.gradle脚本,里面内容如下 task helloword << { println 'Hello gradle qick start' } 2.在do ...

  2. python django url直接访问txt文件。urls.py路由直接指向txt文件

    from django.views.generic import TemplateView urlpatterns = [ url(r'^test/',TemplateView.as_view(tem ...

  3. J2EE中的过滤器和拦截器

    过滤器和拦截器的相似之处就是拦截请求,做一些预处理或者后处理. 而过滤器和拦截器的区别在于过滤器是相对HTTP请求而言的,而拦截器是相对Action中的方法的. 过滤器:访问web服务器的时候,对一个 ...

  4. flash判断,及安装注意

    使用下面方法判断flash版本 function flashChecker() { var hasFlash = 0; //是否安装了flash var flashVersion = 0; //fla ...

  5. ItelliJ Idea 2019提交TFVC变更,系统提示Validation must be performed before checking in

    问题描述 全新安装的Idea 2019,从Azure DevOps Server 2019 (原名TFS)的TFVC代码库下载文件,正常. 修改代码后,签入,系统提示"Validation ...

  6. COMP 2406 – F19

    COMP 2406 – F19 – A4 Due Friday, November 22nd at 11:59 PMAssignment 4 Trivia Quiz BuilderSubmit a s ...

  7. Linux查找文件夹下包含某字符的所有文件

    Linux grep 命令用于查找文件里符合条件的字符串.grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设 grep 指令会把含有范本样式的那一列显示 ...

  8. spring的@ControllerAdvice注解

    @ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理. 对于@ControllerAdvic ...

  9. RocketMQ多master多salve集群搭建

    一.RocketMQ集群模式简介 单Master方式 风险比较大, 一旦Broker重启或者宕机, 将导致整个环境不可用, 不建议线上使用. 多Master模式 一个集群中没有slave, 全是mas ...

  10. mysql参数之innodb_buffer_pool_size大小设置

    用于缓存索引和数据的内存大小,这个当然是越多越好, 数据读写在内存中非常快, 减少了对磁盘的读写. 当数据提交或满足检查点条件后才一次性将内存数据刷新到磁盘中.然而内存还有操作系统或数据库其他进程使用 ...