「CodePlus 2017 11 月赛」汀博尔 (二分答案)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「CodePlus 2017 11 月赛」汀博尔 (二分答案)相关的知识,希望对你有一定的参考价值。

题目链接:https://loj.ac/problem/6249

题意:有 n 棵树,初始时每棵树的高度为 H?i?,第 i 棵树每月都会长高 A?i??。现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于 L,而且木料必须是整棵树(即不能为树的一部分)。

现在问你最少需要等多少个月才能满足订单。(数据范围:1<=n<=200000,1<=S,L<=1e18,1<=Hi,Ai<=1e9

题解:很显然二分答案。上界不能直接选择1e18,会爆long long(卡在这里好久...)。所以这里要对上界进行处理一下,上界先取1e18,然后根据一棵树能完成需求的时间最小值不断降低时间。

(从一个dalao博客里学到的,ヾ(≧O≦)〃嗷~)

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N=200000+10;
 7 typedef long long LL;
 8 LL H[N],A[N],n,S,L;
 9 
10 int check(LL mid){
11     LL sum=0;
12     for(int i=1;i<=n;i++){
13         if((H[i]+mid*A[i])>=L) sum+=(H[i]+mid*A[i]);
14         if(sum>=S) return 1;
15     }
16     return 0;
17 }
18 
19 int main(){
20     scanf("%lld %lld %lld",&n,&S,&L);
21     for(int i=1;i<=n;i++) scanf("%lld",&H[i]);
22     for(int i=1;i<=n;i++) scanf("%lld",&A[i]);
23     LL l=0,r=1e18,mid,ans;
24     for(int i=1;i<=n;i++) r=min(r,max((S-H[i])/A[i]+1,(L-H[i])/A[i]+1));
25     while(r>=l){
26         mid=(l+r)/2;
27         if(check(mid)) r=mid-1,ans=mid;
28         else l=mid+1;
29     }
30     printf("%lld\n",ans);
31     return 0;
32 }

 

 

 

以上是关于「CodePlus 2017 11 月赛」汀博尔 (二分答案)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj5106 [CodePlus2017]汀博尔 二分

BZOJ5106: [CodePlus2017]汀博尔

「CodePlus 2017 11 月赛」可做题

[LOJ 6248]「CodePlus 2017 11 月赛」晨跑

[CodePlus 2017 11月赛&洛谷P4058]木材 题解(二分答案)

「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!