1. 程式人生 > >「CodePlus 2017 11 月賽」汀博爾 (二分答案)

「CodePlus 2017 11 月賽」汀博爾 (二分答案)

sca https min fix type namespace 題意 滿足 fontsize

題目鏈接: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 月賽」汀博爾 (二分答案)