1. 程式人生 > >[LOJ 6249]「CodePlus 2017 11 月賽」汀博爾

[LOJ 6249]「CodePlus 2017 11 月賽」汀博爾

return 數量 sca col 題解 efi 計算 font +=

Description

有 n 棵樹,初始時每棵樹的高度為 H_i,第 i 棵樹每月都會長高 A_i。現在有個木料長度總量為 S 的訂單,客戶要求每塊木料的長度不能小於 L,而且木料必須是整棵樹(即不能為樹的一部分)。現在問你最少需要等多少個月才能滿足訂單。

Input

第一行 3 個用空格隔開的非負整數 n,S,L,表示樹的數量、訂單總量和單塊木料長度限制。
第二行 n 個用空格隔開的非負整數,依次為 H1,H2,…,Hn。
第三行 n 個用空格隔開的非負整數,依次為 A1,A2,…,An。

Output

輸出一行一個整數表示答案。

Sample Input

3 74 51
2 5 2
2 7 9

Sample Output

7

Hint

對於樣例,在六個月後,各棵樹的高度分別為 14,47,56,此時無法完成訂單。
在七個月後,各棵樹的高度分別為 16,54,65,此時可以砍下第 2 和第 3 棵樹完成訂單了。

n <= 200000, S,L <= 1e18, a,h <= 1e9

來自 CodePlus 2017 11 月賽,清華大學計算機科學與技術系學生算法與競賽協會 榮譽出品。
Credit:idea/鄭林楷 命題/鄭林楷 驗題/王聿中
感謝騰訊公司對此次比賽的支持。

題解

比較裸的二分,主要是數據範圍太惡心,容易爆$longlong$,調了好久...強行開$int128$才過。

 1 //It is made by Awson on 2017.11.27
 2 #include <map>
 3 #include <set>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <cstdio>
 9 #include <string>
10 #include <vector>
11 #include <cstdlib>
12
#include <cstring> 13 #include <iostream> 14 #include <algorithm> 15 #define LL __int128 16 #define Max(a, b) ((a) > (b) ? (a) : (b)) 17 #define Min(a, b) ((a) < (b) ? (a) : (b)) 18 using namespace std; 19 const int N = 200000; 20 21 int n; 22 LL s, l, a[N+5], h[N+5]; 23 24 bool judge(LL mid) { 25 LL cnt = 0; 26 for (int i = 1; i <= n; i++) 27 if (mid >= (l-h[i])/a[i]+(bool)((l-h[i])%a[i])) { 28 cnt += a[i]*mid+h[i]; 29 if (cnt >= s) return true; 30 } 31 return false; 32 } 33 void work() { 34 scanf("%d%lld%lld", &n, &s, &l); 35 for (int i = 1; i <= n; i++) scanf("%lld", &h[i]); 36 for (int i = 1; i <= n; i++) scanf("%lld", &a[i]); 37 LL L = 0, R = Max(l, s), ans; 38 while (L <= R) { 39 LL mid = (R+L)>>1; 40 if (judge(mid)) ans = mid, R = mid-1; 41 else L = mid+1; 42 } 43 printf("%lld\n", ans); 44 } 45 int main() { 46 work(); 47 return 0; 48 }

[LOJ 6249]「CodePlus 2017 11 月賽」汀博爾