Mr. Kitayuta vs. Bamboos

题目链接:http://codeforces.com/problemset/problem/505/E

参考:http://blog.csdn.net/qpswwww/article/details/46316647

贪心,二分

从数据规模上看,算法复杂度只能为O(n)或者O(nlgn),似乎不能直接求值,考虑二分MAX将求值问题转化为判定性问题。然而考虑到砍伐后竹子高度变为0的特殊情况,考虑倒着做,即初始时每个竹子高度均为MAXi,每天晚上每个竹子会减少高度a[i],每天白天可以选择对其中不超过K个竹子选择将其的高度增加P,并且保证任何时刻任何竹子高度均大于等于0,m天后是否可以让每个竹子高度均大于等于h[i]。

证明倒着推的正确性:只有在m天后每个竹子高度均大于等于h[i],才能让所有的竹子按照原来正向的顺序,以和倒着做相同的操作反过来让每个竹子最终的高度小于等于MAXi,见下图,绿色线代表倒着推的话一根竹子的每天生长情况,蓝色线代表正着推的话一根竹子的每天生长情况(来自Codeforces官方题解)

可以发现如果每天对这个竹子的操作相同的话,要想让最后的这个竹子的高度和倒着推的高度一样,之前每天正着推的高度都必须小于等于倒着推的高度。

首先计算从MAXi开始,最多经历多少天自由生长(减少高度a[i]),竹子的高度变为负数,然后用一个小顶堆维护竹子变为负数的天数(时间越小,越快变为负数),每天取k个竹子进行砍伐(拔高处理)。若存在某一天来不及拔高竹子(存在某个竹子的高度在这一天之前就变为0了),就可以立刻判定m天后不能可以让每个竹子高度均大于等于h[i]。

现在我们让所有竹子倒过来生长,最终每个竹子高度均大于等于0后,就需要让每个竹子的高度拔高,使得它们最终高度大于等于h[i],显然此时由于在生长过程中,每个竹子在任意时刻高度均大于等于0,故此时补充的操作无论是在何时发生都是一样的。这时直接通过数学方法,计算每个竹子和h[i]之间相差的高度以考虑需要补上多少次操作就够了。

这道题是看着题解跪着做完的Orz,感觉对二分的理解更深了一些,二分处理的都是判定性问题,不能直接求值。

代码如下:

 #include<cstdio>
#include<queue>
#include<iostream>
#define N 100000
#define LL long long
#define mid ((l+r)>>1)
using namespace std;
const LL MAX=1e15;
LL n,m,k,p,l,r;
LL h[N+],a[N+];
LL now[N+];
typedef pair<LL,LL> P;
struct cmp{
bool operator()(P a,P b){
return a.first>b.first;//小顶堆
}
};
bool judge(LL x){
priority_queue<P,vector<P>,cmp> q;
for(LL i=;i<n;++i){
now[i]=x;//刚开始竹子的高度为MAXi
if(x-m*a[i]>=)continue;//不需要补充高度
q.push(make_pair(x/a[i],i));//P(到零的天数,下标)
}
LL times=;//砍伐次数
for(;times<=k*m;times++){
if(q.empty())break;
P temp=q.top();
q.pop();
if(temp.first<=times/k)return ;//来不及补充高度,竹子在k天前就长成负数
LL index=temp.second;
now[index]+=p;
if(now[index]-m*a[index]>=)continue;//不需要补充高度
q.push(make_pair(now[index]/a[index],index));
}
if(times>k*m)return ;
for(int i=;i<n;++i){
LL temp=m*a[i]+h[i]-now[i];
if(temp<=)continue;
else times+=((temp/p)+(LL)(temp%p!=));//到h[i]还需要多少次补充高度
if(times>k*m)return ;
}
return ;
}
int main(void){
scanf("%I64d%I64d%I64d%I64d",&n,&m,&k,&p);
l=,r=MAX;
for(LL i=;i<n;++i)
scanf("%I64d%I64d",&h[i],&a[i]);
while(l<r){//二分
if(judge(mid))r=mid;
else l=mid+;
}
printf("%I64d\n",l);
}

Mr. Kitayuta vs. Bamboos的更多相关文章

  1. 「CF505E」 Mr. Kitayuta vs. Bamboos

    「CF505E」 Mr. Kitayuta vs. Bamboos 传送门 如果没有每轮只能进行 \(k\) 次修改的限制或者没有竹子长度必须大于 \(0\) 的限制那么直接贪心就完事了. 但是很遗憾 ...

  2. Mr. Kitayuta vs. Bamboos CodeForces - 505E (堆,二分答案)

    大意: 给定$n$棵竹子, 每棵竹子初始$h_i$, 每天结束时长$a_i$, 共$m$天, 每天可以任选$k$棵竹子砍掉$p$, 若不足$p$则变为0, 求$m$天中竹子最大值的最小值 先二分答案转 ...

  3. CF505E Mr. Kitayuta vs. Bamboos

    cf luogu 要使得最高的柱子高度最小,考虑二分这个高度,那么剩下的就是要指定一个操作方案,使得最终每个柱子高度\(\le mid\) 因为有个柱子高度不会\(<0\)的限制,所以正着模拟不 ...

  4. 506C Mr. Kitayuta vs. Bamboos

    分析 代码 #include<bits/stdc++.h> using namespace std; #define int long long ],h[],now[],cnt[]; in ...

  5. @codeforces - 506C@ Mr. Kitayuta vs. Bamboos

    目录 @description@ @solution@ @accepted code@ @details@ @description@ n 个竹子,第 i 个竹子初始高度 hi,在每天结束时将长高 a ...

  6. Codeforces 505E - Mr. Kitayuta vs. Bamboos(二分+堆)

    题面传送门 首先很显然的一点是,看到类似于"最大值最小"的字眼就考虑二分答案 \(x\)(这点我倒是想到了) 然鹅之后就不会做了/wq/wq/wq 注意到此题正着处理不太方便,故考 ...

  7. ACM: Mr. Kitayuta's Colorful Graph-并查集-解题报

    Mr. Kitayuta's Colorful GraphTime Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I6 ...

  8. CodeForces 505B Mr. Kitayuta's Colorful Graph

    Mr. Kitayuta's Colorful Graph Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d ...

  9. Codeforces Round #286 (Div. 2) B. Mr. Kitayuta's Colorful Graph dfs

    B. Mr. Kitayuta's Colorful Graph time limit per test 1 second memory limit per test 256 megabytes in ...

随机推荐

  1. Smallest multiple

    problem 5:Smallest multiple 题意:求最小的正数,使得其可以被1-20整除 代码如下: #ifndef PRO5_H_INCLUDED #define PRO5_H_INCL ...

  2. Google Daydream 在中国的第一次演讲摘录

    从 PC.手机到 VR/AR,计算机平台正在迁移,而在这个过程中,与用户使用体验息息相关的「人机交互方式」也将不可避免的发生变化.作为这几波浪潮的弄潮儿,Google 怎么看这种人机交互方式的演进? ...

  3. Spring 注解式Aop 入门

    首先在spring配置文件中加上 xmlns:aop="http://www.springframework.org/schema/aop" http://www.springfr ...

  4. Chapter 21_3 模式

    很多地方都会看到各种匹配模式,每次接触这些函数,颇使人望文生畏. 今天就来好好面对它.认识它.了解它.最后战胜它. 匹配模式都是用一串常规的字符串来描述,最主要的是理解这些字符串的语法及含义(即它能匹 ...

  5. CODE[VS]-求和-整数处理-天梯青铜

    题目描述 Description 求n个数的和 输入描述 Input Description 第一行一个整数n 接下来一行n个整数 输出描述 Output Description 所有数的和 样例输入 ...

  6. String使用拼接对性能的影响和原因。

    需要频繁的拼接String的时候,使用\'+\'拼接会影响性能,应该用StringBuilder或者StringBuffer的append反方法来拼接,从执行速度上来讲:StringBuilder & ...

  7. 面向对象UML中类关系

    如果你确定两件对象之间是is-a的关系,那么此时你应该使用继承:比如菱形.圆形和方形都是形状的一种,那么他们都应该从形状类继承而不是聚合.如果你确定两件对象之间是has-a的关系,那么此时你应该使用聚 ...

  8. (从零开始java开发) IDEA+MAVEN构建一个webapp骨架项目(解决一直downloading问题)

    折腾了一段时间终于解决了, 可能是因为网络问题 xml一直没法访问 maven 骨架生成项目速度慢的令人发指,都在Generating project in Batch mode等待,Idea状态显示 ...

  9. As input tri-stated

    前些日子正好看到了riple兄的<一波三折--危险的"未分配"引脚>一文,颇受启发.正好最近也遇上了类似的问题,也可谓一波三折,还好最后摆平了,要不煮熟的鸭子可就要飞了 ...

  10. Buffett saying

    1. 人生财富就像滚雪球,最重要的是发现很湿的雪和很长的坡. 2. 雪球想滚大,必须要有最坚实的核心:一生坚持的价值投资理念 价值投资一直是巴菲特投资理念的核心,他始终认为投资企业最重要的是要看准企业 ...