题目描述
有 n 棵树,初始时每棵树的高度为 Hi,第 i 棵树每月都会长高 Ai。现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于
L,而且木料必须是整棵树(即不能为树的一部分)。现在问你最少需要等多少个月才能满足订单。
输入格式
从标准输入读入数据。
第一行 3 个用空格隔开的非负整数 n,S,L,表示树的数量、订单总量和单块木料长度限制。
第二行 n 个用空格隔开的非负整数,依次为 H1,H2,…,Hn。
第三行 n 个用空格隔开的非负整数,依次为 A1,A2,…,An。
输出格式
输出到标准输出。
输出一行一个整数表示答案。
样例1输入
3 74 51
2 5 2
2 7 9
样例1输出
7
Hints
对于样例,在六个月后,各棵树的高度分别为 14,47,56,此时无法完成订单。
在七个月后,各棵树的高度分别为 16,54,65,此时可以砍下第 2 和第 3 棵树完成订单了。
思路
二分月份,然后判断当前月份是否满足条件,注意long long
区间大小是从-1到订单总量到单个木料限制的最大值
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
const ll N=200000+20;
ll a[N],h[N];
ll n,s,limit;
inline ll read()
{
ll ret=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9')
{
ret=ret*10-48+ch;
ch=getchar();
}
return ret;
}
ll judge(ll time)
{
ll sum=0;
for(ll i=1; i<=n; i++)
{
if(limit>h[i]&&time<=(limit-h[i]-1)/a[i])
continue;
if(time>=(s-h[i])/a[i])
return 1;
sum+=time*a[i]+h[i];
if(sum>=s)
return 1;
}
return 0;
}
int main()
{
scanf("%lld%lld%lld",&n,&s,&limit);
for(ll i=1; i<=n; i++) h[i]=read();
for(ll i=1; i<=n; i++) a[i]=read();
ll l=-1,r=max(limit,s);
while(l+1<r)
{
ll mid=(l+r)>>1;
if(judge(mid))
r=mid;
else
l=mid;
}
printf("%lld\n",r);
return 0;
}