【bzoj5106: [CodePlus2017]汀博尔】二分查找

5106: [CodePlus2017]汀博尔

Time Limit: 10 Sec   Memory Limit: 512 MB
Submit: 101   Solved: 43
[ Submit][ Status][ Discuss]

Description

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

Input

第一行3个用空格隔开的非负整数n,S,L,表示树的数量、订单总量和单块木料长
度限制。
第二行n个用空格隔开的非负整数,依次为H1,H2,...,Hn。
第三行n个用空格隔开的非负整数,依次为A1,A2,...,An。
1<=N<=200000,1<=S,L<=10^18,1<=Hi,Ai<=10^9

Output

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

Sample Input

3 74 51
2 5 2
2 7 9

Sample Output

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

HINT

来自 CodePlus 2017 11 月赛,清华大学计算机科学与技术系学生算法与竞赛协会 荣誉出品。

Credit:idea/郑林楷 命题/郑林楷 验题/王聿中

Git Repo:https://git.thusaac.org/publish/CodePlus201711

本次比赛的官方网址:cp.thusaac.org

感谢腾讯公司对此次比赛的支持。


裸的二分查找题,就是要判断一下不能让中间运算超过long long就可以ac了

#include<cstdio>
#include<iostream>
#define ll long long
#define N 200005
#define INF (ll)1e18
using namespace std;
ll S,L,h[N],a[N],mx=-1;
int n;
bool check(ll x){
	ll s=0;
	for(int i=1;i<=n;i++)
		if(a[i]*x+h[i]>=L) s+=a[i]*x+h[i];
	return s>=S;
}
int main(){
	scanf("%d%lld%lld",&n,&S,&L);
	for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]),mx=max(mx,a[i]);
	ll l=0,r=1+max(S,L)/mx,mid;
	while(l<r){
		mid=(l+r)/2;
		if(check(mid)) r=mid;else l=mid+1;
	}
	printf("%lld\n",r);
}


猜你喜欢

转载自blog.csdn.net/bingoo0o0o/article/details/78740472