BZOJ5106: [CodePlus2017]汀博尔

Posted mt-li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ5106: [CodePlus2017]汀博尔相关的知识,希望对你有一定的参考价值。

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 棵树完成订单了。
 
 
SB二分
 
代码如下:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
ll S,L;
ll a[2100000],h[2100000];
bool check(ll p)
{
    ll sum=S;
    for(int i=1;i<=n;i++)
    {
        if(a[i]+h[i]*p>=L)sum-=a[i]+h[i]*p;
        if(sum<=0)return true;
    }
    if(sum<=0)return true;
    return false;
}
int main()
{
    scanf("%d%lld%lld",&n,&S,&L);
    ll maxx=0;
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&h[i]);
        maxx=max(maxx,(ll)(max(S,L)-a[i])/h[i]+100);
    }
    ll l=0,r=maxx,ans;
    while(l<=r)
    {
        ll mid=(l+r)/2;
        if(check(mid)==true){ans=mid;r=mid-1;}
        else l=mid+1;
    }
    printf("%lld\n",ans);
    return 0;
}

by_lmy

以上是关于BZOJ5106: [CodePlus2017]汀博尔的主要内容,如果未能解决你的问题,请参考以下文章

「CodePlus 2017 11 月赛」汀博尔 (二分答案)

[LOJ 6249]「CodePlus 2017 11 月赛」汀博尔

bzoj5105: [CodePlus2017]晨跑

BZOJ5105: [CodePlus2017]晨跑

bzoj5108 [CodePlus2017]可做题 位运算dp+离散

BZOJ5110[CodePlus2017]Yazid 的新生舞会 线段树