「POI2012」井 Well
description
你要挖井,\(n\)个地面的高度可视为\(h_i\),每次操作你可以将一个\(h_i-1\),你最多可执行\(m\)次操作。
你要任选其中一个\(h_i\)挖到\(0\),问你相邻的高度差的最大值最小。并输出满足其的最小的井。
solution
二分最大值\(mid\)。
先不考虑挖井到0。用最少的步数,把\(h\)削到满足条件。
削我一开始想到是用堆,每次最小的那个肯定不会被削,削它两边的。\(O(nlog^2n)\)
其实直接从左往右,削左小右大的;再从右往左削左大右小的。\(O(nlogn)\)
证明?第一遍后不存在\(h_{i+1}-h_i>mid\),第二遍会保持第一遍的性质(对于第一遍被削的\(i,i+1\),显示\(i+1\)如果被削且差大于了\(mid\),当且仅当他们大小颠倒变为左大右小,然后下一步会把\(i\)削合法),且满足\(h_{i-1}-h_i<=mid\)。得证。
从左往右枚举每个当井。从\(h_i\)->\(0\)必然,会牵涉到两边,即一个区间\([l,r]\)降低。
具体的,两边在斜率为\(-mid\),\(mid\)过该店的直线上方的点会被削到刚好在直线上。
只要有一个本身在直线下的点,之后都会在直线下,因此是一个区间。
随着井\(i\)->\(i+1\),区间相当于双指针,都会往右移。
证明?对于左边部分的直线变高,在直线下的更多,缩范围;同理而右边直线会变低,直线下的更少,阔范围。
总结:二分+削减+枚举井(维护双指针)
code:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,h[N],a[N],up;
ll s[N],m;
ll calc(int t,ll ch) {
if(!t)return 0;
return (ch*t+ch)*t/2;
}
int check(ll mid) {
// printf("%d:~~~~~~\n",mid);
for(int i=1;i<=n;i++)h[i]=a[i];
ll pay=0;
for(int i=2;i<=n;i++) if(h[i]-h[i-1]>mid){pay+=h[i]-h[i-1]-mid;h[i]=h[i-1]+mid;}//左小右大
for(int i=n-1;i;i--) if(h[i]-h[i+1]>mid){pay+=h[i]-h[i+1]-mid;h[i]=h[i+1]+mid;} //左大右小
// printf("pay = %lld\n",pay);
if(pay>m)return 0;
for(int i=1;i<=n;i++) s[i]=s[i-1]+h[i];
int l=1,r=1;
for(int i=1;i<=n;i++) { //井
while(l<i&&h[l]<(i-l)*mid) {l++;} //l满足
while(r<n&&h[r+1]>=(r+1-i)*mid) {r++;} //r不满足
ll cost=pay+s[r]-s[l-1]-(calc(i-l,mid)+calc(r-i,mid));
if(cost<=m) {return i;}
}
return 0;
}
void solve() {
int l=0,r=up,f,id;
while(l<=r) {
int mid=(l+r)>>1,p=check(mid);
if(p) {f=mid;id=p;r=mid-1;}
else {l=mid+1;}
}
printf("%d %d",id,f);
}
int main() {
// freopen("data.in","r",stdin);
scanf("%d%lld",&n,&m);
for(int i=1;i<=n;i++) {scanf("%d",&h[i]);a[i]=h[i];up=max(up,h[i]);}
solve();
return 0;
}
「POI2012」井 Well的更多相关文章
- 「POI2012」约会 Rendezvous
#2691. 「POI2012」约会 Rendezvous 这题我简直不想说什么了,什么素质,卡常数…… “每个顶点有且仅有一条出边”,所以是一道基环树的题,首先tarjan缩点,在缩完点后的图上求a ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
随机推荐
- python-逆序输出
输入一行字符串,然后对其进行如下处理. 输入格式: 字符串中的元素以空格或者多个空格分隔. 输出格式: 逆序输出字符串中的所有元素.然后输出原列表.然后逆序输出原列表每个元素,中间以1个空格分隔.注意 ...
- rabitmq 登录报错:User can only log in via localhost
安装教程参考:https://blog.csdn.net/qq_43672652/article/details/107349063 修改了配置文件仍然报错,无法登录.解决办法:新建一个用户登录: 查 ...
- 【uniapp 开发】uni-app 技术点的链接记录
优雅的H5下拉刷新.零依赖,高性能,多主题,易拓展 https://ask.dcloud.net.cn/article/12772 图像(头像)选择,截取,压缩,上传的分享 https://ask.d ...
- Docker 核心知识回顾
Docker 核心知识回顾 最近公司为了提高项目治理能力.提升开发效率,将之前的CICD项目扩展成devops进行项目管理.开发人员需要对自己的负责的项目进行流水线的部署,包括写Dockerfile ...
- python的字典及相关操作
一.什么是字典 字典是Python中最强大的数据类型之一,也是Python语言中唯一的映射类型.映射类型对象里哈希值(键,key)和指向的对象(值,value)是一对多的的关系,通常被认为是可变的哈希 ...
- Java语言学习day21--7月27日
###01接口的概念 * A:接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的"类". 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实 ...
- 2021.07.19 P2624 明明的烦恼(prufer序列,为什么杨辉三角我没搞出来?)
2021.07.19 P2624 明明的烦恼(prufer序列,为什么杨辉三角我没搞出来?) [P2624 HNOI2008]明明的烦恼 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn ...
- openlayers API实现鹰眼图OverviewMap时地图不断闪烁等问题的解决思路
前言:我吐了,OpenLayers的巨坑之一--鹰眼图OverviewMap创建之必备注意事项. 许久没有更新博客的我,在今天饱受折磨之后一定要分享一下(这么过分一定要说出来.jpg) 相信大家如果使 ...
- Docker极简入门:使用Docker-Compose 运行网站浏览量统计Demo
Docker-Compose 是一个可以对 Docker 容器集群的快速编排的工具,能够减轻您心智和手指的负担. 简单的来说 Docker-Compose 就是将你运行多个容器的命令编写到了一起,类似 ...
- C# 一维数组如何快速实现数组元素的数据类型的转换?
一.场景假设 假设有一串字符串如下所示,字符串中的数字之间已用英文状态下的逗号隔开.要求用此字符串中的数字快速生成int类型的数组,且尽可能使用最少的代码量. string str = "1 ...