bzoj4310
题解:
后缀数组求出本质不同的串
然后二分答案
贪心判断是否可行
代码:
#include<bits/stdc++.h>
const int N=;
using namespace std;
typedef long long ll;
char s[N];
ll L,R,mid;
int K,n,rk[N],sa[N],height[N],tmp[N],cnt[N],Log[N];
int f[][N],g[N],len,nowl,nowr,ansl,ansr;
void SA(int n,int m)
{
n++;
for (int i=;i<n;i++)cnt[rk[i]=s[i]]++;
for (int i=;i<m;i++)cnt[i]+=cnt[i-];
for (int i=;i<n;i++)sa[--cnt[rk[i]]]=i;
for (int k=;k<=n;k<<=)
{
for (int i=;i<n;i++)
{
int j=sa[i]-k;
if (j<)j+=n;
tmp[cnt[rk[j]]++]=j;
}
int j=;
sa[tmp[cnt[]=]]=j=;
for (int i=;i<n;i++)
{
if (rk[tmp[i]]!=rk[tmp[i-]]||rk[tmp[i]+k]!=rk[tmp[i-]+k])cnt[++j]=i;
sa[tmp[i]]=j;
}
memcpy(rk,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if (j>=n-)break;
}
for (int i,k,j=rk[height[i=k=]=];i<n-;i++,k++)
while (~k&&s[i]!=s[sa[j-]+k])height[j]=k--,j=rk[sa[j]+];
}
int lcp(int x,int y)
{
if (x==y)return n-x;
x=rk[x],y=rk[y];
if (x>y)swap(x,y);
int k=Log[y-x];
return min(f[k][x+],f[k][y-(<<k)+]);
}
void kth(ll k)
{
ll s=;
for (int i=;i<=n;s+=n-sa[i]-height[i],i++)
if (s+n-sa[i]-height[i]>=k)
{
nowl=sa[i],nowr=nowl+height[i]+k-s-;
len=nowr-nowl+;
return;
}
}
int ask(int l,int r)
{
int t=min(lcp(l,nowl),min(r-l+,len));
if (t==r-l+&&t<=len)return ;
if (t==len)return ;
return s[l+t]<=s[nowl+t];
}
int check()
{
int j,k=;
for (int i=n-;~i;i=j,k++)
{
for (j=i;~j;j--)
if (!ask(j,i))break;
if (j==i)return ;
}
return k<=K;
}
int main()
{
scanf("%d%s",&K,s);
n=strlen(s);
SA(n,);
for (int i=;i<=n;i++)Log[i]=Log[i>>]+;
for (int i=;i<=n;i++)f[][i]=height[i];
for (int j=;j<;j++)
for (int i=;i+(<<j-)<=n;i++)f[j][i]=min(f[j-][i],f[j-][i+(<<j-)]);
for (int i=;i<=n;i++)R+=n-sa[i]-height[i];
while (L<=R)
{
kth(mid=(L+R)>>);
if (check())ansl=nowl,ansr=nowr,R=mid-;
else L=mid+;
}
for (int i=ansl;i<=ansr;i++)putchar(s[i]);
return ;
}
bzoj4310的更多相关文章
- 【BZOJ4310】跳蚤
[BZOJ4310]跳蚤 Description 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他 ...
- BZOJ4310 跳蚤(后缀数组+二分答案)
注意到答案一定是原串的子串,于是考虑造出SA,二分答案是第几小的子串.第k小子串很容易在SA上求出.之后计算使他成为最大子串至少要在几个位置切割,对每个字典序比答案大的后缀,找到所有合法切割位置(求l ...
- [BZOJ4310] 跳蚤 - 后缀数组,二分,ST表
[BZOJ4310] 跳蚤 Description 首先,他会把串分成不超过 \(k\) 个子串,然后对于每个子串 \(S\) ,他会从 \(S\) 的所有子串中选择字典序最大的那一个,并在选出来的 ...
- 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分
4310: 跳蚤 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 180 Solved: 83[Submit][Status][Discuss] De ...
- BZOJ4310 : 跳蚤
首先求出后缀数组,得到本质不同的子串的个数. 然后二分答案,每次先通过后缀数组求出第$mid$小的子串,然后贪心进行检验. 检验的时候,从后往前贪心,每次加入一个后缀,如果不能加了,那就划为一段. 时 ...
- BZOJ4310: 跳蚤 【后缀数组+二分】
Description 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究.首先,他会把串 分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典 ...
- 【bzoj4310/hdu5030-跳蚤】后缀数组
我真的是..调了一百年.. 傻逼的人生.. 而且这题好像可以用sam做哎!我Y出了一个奇怪的办法.. 好吧sam是不能做这题的.搞错了. 说说后缀数组好了.. 搞后缀数组 然后我们要二分一个子串,判断 ...
- 【bzoj4310】跳蚤 后缀数组+二分
题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...
- [BZOJ4310] 跳蚤 SAM || SA
没有代码的. 传送门 先二分出第 \(mid\) 大的字串 \(s\),然后从后往前切割,每次大于 \(s\) 了就不行. 涉及到的操作:求第 \(mid\) 大子串:比较两个字串(求 \(lcp\) ...
随机推荐
- 关于datatables自适应以及自定义列宽度的总结
table-layout:fixed;可以自定义列的宽度 <div id="bizhi" style="width:100%;height: 85%;overflo ...
- Windows下tomcat启动一闪而过
1.用记事本打开tomcat/bin/setclasspath.bat 2.添加两行代码,jdk和jre的根目录,相当于直接给出JAVA_HOME和JRE_HOME路径 set JRE_HOME=D: ...
- postMan用法
增加: 删除: 更改: 查询:
- 第 3 章 镜像 - 017 - RUN vs CMD vs ENTRYPOINT
RUN.CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆. 简单的说: RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包. CMD 设置容器启动 ...
- C# 递归缩小图片
需求:图片太大,上传到服务器会非常占用服务器空间,而系统又不要求高清图片,于是就通过递归的方式让图片每次减少10%的大小,当图片大小小于100k的时候就保存在本地,核心代码如下: class Prog ...
- MATLAB 矩阵处理基础
- 利用unittest+ddt进行接口测试(二):使用yaml文件管理测试数据
知道ddt的基本使用方法之后,练习把之前用excel文件来维护的接口测试用例改用unittest+ddt来实现. 这里我选用yaml文件来管理接口参数,开始本来想用json,但是json无法添加注释, ...
- Adobe Photoshop CC 2018 v19.0 简体中文正式版下载安装破解(附注册机+破解教程) 32/64位(安装破解注意事项是什么)
Adobe Photoshop CC 2018 v19.0 简体中文正式版下载安装破解(附注册机+破解教程) 32/64位(安装破解注意事项是什么) 一.总结 一句话总结:下载安装破解教程文中都有,需 ...
- redis在php运行时出现错误
我的redis版本:3.2.8. redis安装教程,参考官方网站: https://redis.io/download 在网上多番查找,很多说是配置文件redis.conf中的: # bind 12 ...
- 通过 rufus 创建启动U盘,安装 VMWare Esxi
现在谁还用光盘安装系统啊. 做出启动盘后,U盘启动进行安装才是王道. https://www.starwindsoftware.com/blog/create-an-esxi-6-5-installa ...