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 }
时间: 2024-11-07 13:23:18