bzoj4486: [Jsoi2015]串分割
肉丝哥哥钦定好题 话说我的blog现在为什么到处都是肉丝哥哥
先来想一个弱化版,假如能够n整除K怎么做?
把每个数字看成一个字符串,按字典序排名,这个可以后缀数组解决,然后暴力枚举每种情况,O(1)判两个长度为n/K的数字大小即可
然后不能整除一定是有n-n/K*K个长度为n/K+1的数字
先二分答案排名,枚举起始位置,考虑一个贪心的做法,假如当前能够放一个长度为n/K+1的就立刻放,这样能够保证最优
why?放n/K+1和n/K的区别相当于多往前走了1步,但是多用了一组n/K+1,假如走n/K在未来某一决策能够走n/K+1,那么当前走n/K+1只需付出少用一组就可以拉回同一起跑线。其实也就是具有决策包容性
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int _=1e2;
const int maxn=*2e5+_;
int n,K,U;char ss[maxn]; int sa[maxn],Rank[maxn];
namespace SA
{
int Rsort[maxn],tt[maxn];
void getsa(int n,int m)
{
for(int i=;i<=n;i++)Rank[i]=ss[i]-''; memset(Rsort,,sizeof(Rsort));
for(int i=;i<=n;i++)Rsort[Rank[i]]++;
for(int i=;i<=m;i++)Rsort[i]+=Rsort[i-];
for(int i=n;i>=;i--)sa[Rsort[Rank[i]]--]=i; int ln=,p=;
while(p<n)
{
int k=;for(int i=n-ln+;i<=n;i++)tt[++k]=i;
for(int i=;i<=n;i++)
if(sa[i]-ln>)tt[++k]=sa[i]-ln; memset(Rsort,,sizeof(Rsort));
for(int i=;i<=n;i++)Rsort[Rank[tt[i]]]++;
for(int i=;i<=m;i++)Rsort[i]+=Rsort[i-];
for(int i=n;i>=;i--)sa[Rsort[Rank[tt[i]]]--]=tt[i]; for(int i=;i<=n;i++)tt[i]=Rank[i]; p=;Rank[sa[]]=;
for(int i=;i<=n;i++)
{
if(tt[sa[i]]!=tt[sa[i-]]||tt[sa[i]+ln]!=tt[sa[i-]+ln])p++;
Rank[sa[i]]=p;
} m=p;ln*=;
}
}
void GetTrueRank(int n)
{
int p=;
for(int i=;i<=*n-;i++)
if(sa[i]<=n)Rank[sa[i]]=Rank[sa[i]+n]=++p; for(int i=;i<=n;i++)sa[Rank[i]]=i;
}
void main(int n){getsa(*n-,);GetTrueRank(n);}
} namespace PRINT
{
void main(int ans,int len)
{
int st=sa[ans];
for(int i=;i<=len;i++)putchar(ss[i+st-]);
puts("");
}
}
namespace SOL1
{
void main()
{
int ans=(<<);
for(int i=;i<=U;i++)
{
int num=,tt=;
for(int j=;j<=K;j++)
num=max(num,Rank[i+tt]),tt+=U;
ans=min(ans,num);
}
PRINT::main(ans,U);
}
}
namespace SOL2
{
int calc(int em)
{
int mmax=;
for(int i=;i<=U+;i++)
{
int p=i,num=;
for(int j=;j<=K;j++)
{
if(Rank[p]<=em)p+=U+,num++;
else p+=U;
if(p>=i+n-)break;
}
mmax=max(mmax,num);
}
return mmax;
}
void main()
{
int res=n-U*K;
int el=,er=n,em,ans;
while(el<=er)
{
em=(el+er)/;
if(calc(em)>=res)
{
er=em-;
ans=em;
}
else el=em+;
}
PRINT::main(ans,U+);
}
} int main()
{
scanf("%d%d%s",&n,&K,ss+); U=n/K;
for(int i=;i<n;i++)ss[i+n]=ss[i];
SA::main(n); if(n%K==)SOL1::main();
else SOL2::main(); return ;
}
bzoj4486: [Jsoi2015]串分割的更多相关文章
- 「JSOI2015」串分割
「JSOI2015」串分割 传送门 首先我们会有一个贪心的想法:分得越均匀越好,因为长的绝对比短的大. 那么对于最均匀的情况,也就是 \(k | n\) 的情况,我们肯定是通过枚举第一次分割的位置,然 ...
- C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出
C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出 strstr() 命令是在原字符串中查找指定的字符串第一次出现的地址,用这个特性可以实现字符的分割,判断是否包涵等功能: ...
- Minimum Palindromic Factorization(最少回文串分割)
Minimum Palindromic Factorization(最少回文串分割) 以下内容大部分(可以说除了关于回文树的部分)来自论文A Subquadratic Algorithm for Mi ...
- 【bzoj4486】【JSOI2015】串分割
老省选题了. 首先考虑怎么比较超长数字的大小? 参见UTR1的那道题 先比size,然后比较字典序即可. 接下来考虑下切割的问题. 因为要将字符串切割成k份,所以这个字符串只会存在n/k个本质不同的起 ...
- Java开发笔记(三十七)利用正则串分割字符串
前面介绍了处理字符串的常用方法,还有一种分割字符串的场景也很常见,也就是按照某个规则将字符串切割为若干子串.分割规则通常是指定某个分隔符,根据字符串内部的分隔符将字符串进行分割,例如逗号.空格等等都可 ...
- Codeforces 898 贪心关闭最少闹钟 优先队列最少操作构造N/2squares 讨论情况哈希数字串分割a+b=c
A /* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) ...
- [暑假的bzoj刷水记录]
(这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊 堆一起算了 隔一段更新一下. 7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- SAM 做题笔记(各种技巧,持续更新,SA)
SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...
随机推荐
- Socks5代理Socks5 Proxy
Socks5代理Socks5 Proxy Socks5代理是基于Socks协议的一种代理模式.其中,5表示该协议的版本号.它可以让局域网的计算机通过socks5代理服务器,访问外网的内容.由于它工 ...
- bzoj 1552: [Cerc2007]robotic sort
1552: [Cerc2007]robotic sort Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1198 Solved: 457[Submit] ...
- 1007 Maximum Subsequence Sum
Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to ...
- nginx 自签名https
繁杂的命令,以下准备写好的sh,拷贝https.sh文件,设置执行权限:chmod u+x https.sh #!/bin/sh # create self-signed server certifi ...
- Android重写view时onAttachedToWindow () 和 onDetachedFromWindow ()
在重写View的时候,会遇到这两个方法 protected void onAttachedToWindow() Description copied from class: View This is ...
- linux安装开源邮件服务器iredmail的方法:docker
直接安装的方法,参考网文,我不介绍.本文介绍的是快速的方法:docker 使用镜像源:https://hub.docker.com/r/lejmr/iredmail/,因为pull的数量最多 直接 d ...
- 为什么硬盘明明还有空间,linux却说硬盘空间不足?inode;mkdir: 无法创建目录"shen1": 设备上没有空间
现象:df -h显示硬盘还有14G空间,但是touch file/mkdir directory都失败,提示硬盘没有空间 原因:df -ia查看下inode的使用情况,发现已经爆了,(下图显示使用88 ...
- 请问如何突破”所选文件超出了文件的最大值设定:25.00 Mb“限制
警告消息 这个限制 并没有 设置项, 必须 修改 源码才可以. 打开 web/static/src/js/views/form_widgets.js ...
- Solaris设备管理
接手一台服务器,如何了解它的软硬件配置 数据库可以装在裸设备上,何为裸设备 知识点: 内核 驱动程序 设备命名 设备访问方式 磁盘的管理 内核: 指挥硬件干活的工具,shell翻译官,将人类语言翻译为 ...
- python(3)- 循环语句:从最内层跳出多层循环
跳出多层循环:三层循环,最里层直接跳出3层 方法一: 在Python中,函数运行到return这一句就会停止,因此可以利用这一特性,将功能写成函数,终止多重循环 def work(): #定义函数 f ...