题意

有一个非负整数序列\({a_i}\),你要将他分成恰好\(k\)段,记\(s_i\)为第\(i\)段的和,\(m_i\)为第\(i\)段的最大值,你需要保证这种划分方案对任意\(1 \le i < k\)满足:\(|s_i-s_{i+1}|\le \max(m_i,m_{i+1})\)

\(3 \leq k \leq n \leq 100\,000\)

传送门

思路

题解中的给出的分割为和的平方最小的,请自星阅读,其实最终实现方法也可以互通

我们定义“对序列进行一次\(x\)划分”为(从前往后或从后往前)扫一遍序列,每当权值和大于等于\(x\)就分一段。

二分出最大的\(x\)满足划分后段数\(\ge k\)(注意不算最后的和不到的零头段),令其为\(mid\)。

如果对序列进行\(mid\)划分后序列被恰好分成了\(k\)段,那么这种划分方案在原问题下就是最优的且合法的。

证明:考虑两段划分,\(mid-x_i\)表示除最后一个外的和(\(x_i >0\)),那么\(mid-x_i+last_i-(mid-x_{i+1}+last_{i+1})\le last_i \leq m_i\)。所以一定是小于等于最大值的

若不满足,则可以对序列倒着做\(mid+1\)分段,通过某种方式(这里的证明比较随意,感性理解一下)可以证明正着做\(mid\)分段与倒着做\(mid+1\)分段存在至少一个公共划分点,且满足用前者划分的一段前缀拼上后者划分的一段后缀恰好可以得到原问题的一组合法解。

一波乱证:因为二分出的是最大的答案,\(mid+1\)划分个数\(k-a(a>0)\)肯定小于\(mid\)划分个数\(k+b(b \ge 0)\)

反证

如果没有重合点,那么肯定有一段\(mid+1\)划分会包含\(mid\)划分(左右端点不同的),但是可知\(mid\)划分加上一个正整数(在贪心过程中0不会出现在\(mid\)右端点以及\(mid+1\)左端点,可以忽略)肯定可以\(\ge mid+1\),而这里多加了至少两个数所以矛盾

然后要使加起来个数=k的话每出现一个重合点块数就会-1或-0(一段都重合),不出现就不会,换句话说,每一个使块数\(-1\)的点都是重合点。因为\((l_{mid}<l_{mid+1},r_{mid}<r_{mid+1})\),所以一定能找到一个重合点,使得两者加起来刚好为k

至于代码那是非常的简短,但是这思路也是神仙了

#include <bits/stdc++.h>
typedef long long ll;
const int N=100005;
int n,a[N],p[N],p2[N],k;
long long l,r,ans;
int check(ll x){
ll sum=0;int cnt=0;
for (int i=1;i<=n;i++){
sum=sum+a[i];
if (sum>=x) cnt++,sum=0;
}
return cnt;
}
int main(){
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++) scanf("%d",&a[i]),r=r+a[i];
while (l<=r){
ll mid=(l+r)>>1;
if (check(mid)>=k){
ans=mid;
l=mid+1;
}else r=mid-1;
}
puts("Yes");
ll sum=0;int cnt=0;
for (int i=1;i<=n;i++){
sum=sum+a[i];
if (sum>=ans) p[++cnt]=i,sum=0;
}
if (p[cnt]==n && cnt==k){
for (int i=1;i<cnt;i++) printf("%d ",p[i]);
puts("");
return 0;
}
sum=0;int cnt2=0;
for (int i=n;i>=1;i--){
sum=sum+a[i];
if (sum>=ans+1) p2[++cnt2]=i,sum=0;
}
for (int i=1;i<=cnt;i++){
if (p[i]==p2[k-i]-1){
for (int j=1;j<=i;j++) printf("%d ",p[j]);
for (int j=k-i-1;j>=1;j--) printf("%d ",p2[j]-1);
puts("");
break;
}
}
return 0;
}

后记

想不到系列

[300iq contest1-J]Jealous Split的更多相关文章

  1. 2016 Al-Baath University Training Camp Contest-1 J

    Description X is fighting beasts in the forest, in order to have a better chance to survive he's gon ...

  2. 300iq Contest 1 简要题解

    300iq Contest 1 简要题解 咕咕咕 codeforces A. Angle Beats description 有一张\(n\times m\)的方阵,每个位置上标有*,+,.中的一种. ...

  3. React使用antd Table生成层级多选组件

    一.需求 用户对不同的应用需要有不同的权限,用户一般和角色关联在一起,新建角色的时候会选择该角色对应的应用,然后对应用分配权限.于是写了一种实现的方式.首先应用是一个二级树,一级表示的是应用分组,二级 ...

  4. 利用poi导出Excel

    import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.r ...

  5. BZOJ3197 & 组合乱搞

    Description    求\[\sum_{i = 1}^{n}i^m m^i , m \leq 1000 \] 的值.Solution    From Miskcoo's Space:      ...

  6. JavaScript状态机程序逻辑编辑器

    制作背景 之前做Win8 Metro动态加载内容框架的时候,由于采用了XAML+JavaScript的方法,程序复杂的执行逻辑是由JavaScript控制的,而页面一多,流程一复杂,制作起来就非常麻烦 ...

  7. Python开发【前端】:JavaScript

    JavaScript入门 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本 ...

  8. Winform-DataGridView 实现如Excel的粘贴复制

    void AddDataGridView(DataGridView gridView, string s) { s = s.Replace("/", @"\") ...

  9. java动手动脑和课后实验型问题String类型

    1.请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? true true false 总结: 使用new关键字创建字符串对象时, 每次申请 ...

随机推荐

  1. wind安装Jenkins+sonar+jdk

    最近公司在用Jenkins持续集成软件,自己研究的头痛,而且还是和C#项目融合到一起的,网上看到的都是Java的,我自己配了一套和C#的,和你们分享. Jenkins是一个开源软件项目,旨在提供一个开 ...

  2. 独热编码(One-Hot)的理解

    https://www.imooc.com/article/35900 参考上面大神的原文,说的非常透彻.非常便于理解.感谢 感谢 自己做个小笔记,便于自己学习 特征值是离散的,无序的. 如: 性别特 ...

  3. Laravel入门及实践,快速上手ThinkSNS+二次开发

    温馨提示: l 本文纯干货,文字和代码居多,且适合零基础Laravel学习者: l 本文会新建一个名为 blog 的 Laravel 程序,这是一个非常简单的博客. l  欢迎随时关注ThinkSNS ...

  4. 内部属性[[class]]

    1. 对象的[[class]]属性 所有typeof返回值为“object”的对象(如数组)都包含一个内部属性[[class]],这个属性无法直接访问,一般通过Object.prototype.toS ...

  5. Django:实现读写分离

    库的配置 1.读写分离 settings配置 #settings.py 配置库信息,生成2个库 DATABASES = { 'default': { 'ENGINE': 'django.db.back ...

  6. 记录一次git回滚代码

    老大临时让更新一版代码到本地,熟练的git fetch/git merge 之后,出来了一批改动的文件,但是并不是我改动的. 我以为是版本迭代出来的其他同事改的,我就直接给add commit到我的版 ...

  7. MySQL Execution Plan--IN子查询对UPDATE语句影响

    问题描述 在系统中发现一条执行时间为为44652.060734秒(12.5小时)的慢SQL,SQL语句为: UPDATE ob_internal_task SET OPERATE_STATUS WHE ...

  8. mysql的innodb数据存储结构

    ​ 数据库磁盘读取与系统磁盘读取 1,系统从磁盘中读取数据到内存时是以磁盘块(block)为基本单位,位于同一个磁盘块中的数据会被一次性读取出来. 2,innodb存储引擎中有页(Page)的概念,页 ...

  9. Luogu P2114/ACAG 0x01-5 起床困难综合征

    Luogu P2114/ACAG 0x01-5 起床困难综合征 本题的关键之处在于,题目中给定的三种位运算--AND,OR,XOR,在二进制下皆是不进位的.这说明每一位都是独立的,启发我们可以按位考虑 ...

  10. 关于 ES5 & ES6 数组遍历的方法

    ES5 数组遍历方法 1.for 循环 , , , , ] ; i < arr.length; i++) { console.log(arr[i]) } 2.forEach , , , , ] ...