admin 管理员组

文章数量: 1087649

二分——汀博尔

题目链接

二分——汀博尔

题目描述

有 n 棵树,初始时每棵树的高度为 Hi,第 i 棵树每月都会长高 Ai。现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于 L,而且木料必须是整棵树(即不能为树的一部分)。现在问你最少需要等多少个月才能满足订单。

输入描述

第一行 3 个用空格隔开的非负整数 n,S,L,表示树的数量、订单总量和单块木料长度限制。
第二行 n 个用空格隔开的非负整数,依次为 H1,H2,… ,Hn
第三行 n 个用空格隔开的非负整数,依次为 A1,A2,… ,An

输出描述

输出一行一个整数表示答案。

示例

输入

3 74 51
2 5 2
2 7 9

输出

7

说明

对于样例,在六个月后,各棵树的高度分别为 14,47,56,此时无法完成订单。
在七个月后,各棵树的高度分别为 16,54,65,此时可以砍下第 2 和第 3 棵树完成订单了。

备注

1 ≤ n ≤ 200000,1 ≤ S,L ≤ 1018,1 ≤ Hi,Ai ≤ 109

分析

这题我们可以将需要等的月数进行二分查找,但需要注意一下二分边界。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll n,s,l,h[maxn],a[maxn],f[maxn],mx=-1;int check(ll mid)
{for(int i=0;i<n;i++){f[i]=h[i]+mid*a[i];		// mid 月后每棵树的高度 }ll sum=0; for(int i=0;i<n;i++){if(f[i]>=l){	// 当树的高度大于等于 l 时,更新 sum 值 sum+=f[i];}if(sum>=s){return 1;}}return 0;
}int main()
{cin>>n>>s>>l;for(int i=0;i<n;i++){cin>>h[i];}for(int i=0;i<n;i++){cin>>a[i];mx=max(mx,a[i]);}ll l=0,r=1e18/mx+1;	// 左右边界 while(l<=r){ll mid=(l+r)/2;if(check(mid)){r=mid-1;}else{l=mid+1;}}cout<<l<<endl;return 0;
}

本文标签: 二分汀博尔