2027: 汀博尔
Time Limit: 1 Sec Memory Limit: 512 MB
Submit: 159 Solved: 38
[Submit][Status][Web Board]
Description
有 nnn 棵树,初始时每棵树的高度为 HiH_iHi,第 iii 棵树每月都会长高 AiA_iAi。现在有个木料长度总量为 SSS 的订单,客户要求每块木料的长度不能小于 LLL,而且木料必须是整棵树(即不能为树的一部分)。现在问你最少需要等多少个月才能满足订单。
Input
第一行 333 个用空格隔开的非负整数 n,S,Ln,S,Ln,S,L,表示树的数量、订单总量和单块木料长度限制。
第二行 nnn 个用空格隔开的非负整数,依次为 H1,H2,…,Hn。
第三行 nnn 个用空格隔开的非负整数,依次为 A1,A2,…,An。
Output
输出一行一个整数表示答案。
Sample Input
3 74 51
2 5 2
2 7 9
Sample Output
7
HINT
测试点编号 | nnn | 特殊约定 |
---|---|---|
1 | n=1n = 1n=1 | 1≤S≤Hi≤100001 \leq S \leq H_i \leq 100001≤S≤Hi≤10000 |
2 | 1≤S,L,Hi,Ai≤100001 \leq S, L, H_i, A_i \leq 100001≤S,L,Hi,Ai≤10000 | |
3 | 1≤n≤10001 \leq n \leq 10001≤n≤1000 | |
4 | ||
5 | ||
6 | 1≤S,L,Hi,Ai≤1091 \leq S, L, H_i, A_i \leq 10^91≤S,L,Hi,Ai≤109 | |
7 | ||
8 | ||
9 | 1≤n≤200001 \leq n \leq 200001≤n≤20000 | |
10 | ||
11 | 1≤S,L≤10181 \leq S, L \leq 10^{18}1≤S,L≤1018,1≤Hi,Ai≤1091 \leq H_i, A_i \leq 10^91≤Hi,Ai≤109 | |
12 | ||
13 | 1≤n≤2000001 \leq n \leq 2000001≤n≤200000 | L=1L = 1L=1 |
14 | S≤LS \leq LS≤L | |
15 | 1≤S,L≤10181 \leq S, L \leq 10^{18}1≤S,L≤1018,1≤Hi,Ai≤1091 \leq H_i, A_i \leq 10^91≤Hi,Ai≤109 | |
16 | ||
17 | ||
18 | ||
19 | ||
20 |
解题思路:
刚开始想都没想直接暴力WA了一发,其实看数据这么大就应该要想到二分了的,这题有个坑点S,L的大小是不一定的,记得考虑。然后就是二分查找月份的问题了,这里需要考虑一下上界的问题,最差的情况就是一棵树刚刚长到max(S,L),这样就没别的树什么事了,所以上界r=min(r,(t-h[i])/a[i]+1)。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=200005;
LL h[maxn],a[maxn],s,l,n;
int check(LL x)
{
LL sum=0,y=0;
for(int i=0;i<n;i++)
{
y=h[i]+a[i]*x;
if(y>=l)sum+=y;
}
if(sum>=s)return 1;
else return 0;
}
int main()
{
LL t,ans=0;
scanf("%lld%lld%lld",&n,&s,&l);
t=max(s,l);
for(int i=0;i<n;i++)
scanf("%lld",&h[i]);
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
LL l=0,r=1e18,mid;
for(int i=0;i<n;i++)
r=min(r,(t-h[i])/a[i]+1);
while(l<=r)
{
mid=(l+r)/2;
if(check(mid))
{
r=mid-1;
ans=mid;
}
else l=mid+1;
}
printf("%lld\n",ans);
return 0;
}