「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 月赛」汀博尔 (二分答案)的主要内容,如果未能解决你的问题,请参考以下文章
[LOJ 6248]「CodePlus 2017 11 月赛」晨跑