题意

有一个非负整数序列\({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. Java自学-控制流程 switch

    Java的 switch 语句 switch 语句相当于 if else 的另一种表达方式 示例 1 : switch switch可以使用byte,short,int,char,String,enu ...

  2. 突然用xcode老版本调试老代码测试新机,报错"Could not find Developer Disk Image"回忆下

    转载:https://www.cnblogs.com/blogwithstudyofwyn/p/6003176.html 说明:更新了手机的到了iOS 10.0.2.真机调试时候提示"Cou ...

  3. JS基础理论相关知识

    1.XHTML和HTML有什么区别 HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言最主要的不同:XHTML 元素必须被正确地嵌套.XHTML 元素必须被关闭.标签名必须用 ...

  4. 红米手机使用应用沙盒一键修改sdk信息

    前面文章介绍了怎么在安卓手机上安装激活XPOSED框架,XPOSED框架的极强的功能各位都介绍过,能不修改APK的前提下,修改系统内核的参数,打个比方在某些应用情景,各位需要修改手机的某个系统参数,这 ...

  5. 笔谈kxmovie开源播放器库的使用

    开源播放器项目 kxmovie(https://github.com/kolyvan/kxmovie),现在仍然是很多刚开始接触播放器开发的程序员的参照范本.以下是我操作kxmovie项目的过程: ( ...

  6. Alpha_7

    一. 站立式会议照片 二. 工作进展 (1) 昨天已完成的工作 a. 体验,测试,并反馈意见 b. 实现其余的琐碎页面,包括蜕变记录,签到卡 c. 已实现“习惯简记”页面.“习惯简记详情”页面.“已养 ...

  7. form组件 初始化

    class MyForm(Form): user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), initial=2, widget= ...

  8. [FreeRTOS]FreeRTOS使用

    转自:https://blog.csdn.net/zhzht19861011/article/details/49819109 FreeRTOS系列第1篇---为什么选择FreeRTOS? FreeR ...

  9. ES6--不定参数

    <一>,在讨论ES6的不定参数之前,我们先一起回顾一下ECMAScript5的无名参数. 早先,javascript提供arguments对象检查函数的所有参数,从而不必定义每一个要用的参 ...

  10. 摘:Windows系统内存计数器理解解析_备忘录_51Testing软件测试网...

    [原创]Windows系统内存计数器理解解析 2008-05-13 11:42:23 / 个人分类:性能测试 说明:本文的计数器以Windows2003为准. 序言;F9n)\%V1a6Z C)?ZV ...