码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-11-26 23:02:08      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:http   高度   ott   ++   printf   namespace   二分   while   text   

题目链接: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 月赛」汀博尔 (二分答案)

标签:http   高度   ott   ++   printf   namespace   二分   while   text   

原文地址:http://www.cnblogs.com/Leonard-/p/7900594.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!