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\) ...
随机推荐
- shell脚本linux命令连续执行
shell命令连续执行的三种方式: 1.命令1:命令2:命令3 依次执行命令,无论前一条命令是否执行成功. 2.命令1 && 命令2 && 命令3 前一条命令执行成功后 ...
- google搜索小技巧
google搜索小技巧 一.总结 一句话总结:But most people may not be using Google search to its full potential.Want to ...
- 20170921xlVBA_SQL蒸发循环查询2
'ARRAY("1991","1992","1993","1994","1996","19 ...
- get post 小结
get参数通过url传递,post放在request body中. get请求在url中传递的参数是有长度限制的,而post没有. get比post更不安全,因为参数直接暴露在url中,所以不能用来传 ...
- linux导出sql数据
1. 导出数据库的数据 在linux命令行下输入 mysqldump -u userName -p dabaseName > fileName.sql 在linux命令行下输入 2. 导出表 ...
- 【PowerDesigner】【6】Table视图同时显示Code和Name
效果图: —————————————————————— 步骤: 文字版: 1,顶部工具栏Tools→Display Preference 2,Columns→List columns右侧按钮 3,勾选 ...
- 关于js原型链
关于原型链,我们先贴上一张图(来自某知乎大佬专栏),然后听我娓娓道来. 先来说说什么是原型? JavaScript 中的对象有一个特殊的 [[Prototype]] 内置属性,其实就是对于其他对象的引 ...
- leetcode-algorithms-33 Search in Rotated Sorted Array
leetcode-algorithms-33 Search in Rotated Sorted Array Suppose an array sorted in ascending order is ...
- SpringBoot项目Shiro的实现(二)
在看此小节前,您可能需要先看:http://www.cnblogs.com/conswin/p/7478557.html 紧接上一篇,在上一篇我们简单实现了一个Springboot的小程序,但我们发现 ...
- C++笔试题总结
1.C和C++的特点与区别? 答:(1)C语言特点:1.作为一种面向过程的结构化语言,易于调试和维护: 2.表现能力和处理能力极强,可以直接访问内存的物理地址: 3.C语言实现了对硬件的编程操作,也适 ...