Code+ B 汀博尔二分答案
Posted Roni
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Code+ B 汀博尔二分答案相关的知识,希望对你有一定的参考价值。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
有 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
输出
7
说明
对于样例,在六个月后,各棵树的高度分别为 14,47,56,此时无法完成订单。
在七个月后,各棵树的高度分别为 16,54,65,此时可以砍下第 2 和第 3 棵树完成订单了。
备注:
1≤n≤200000,1≤S,L≤1018,1≤Hi,Ai≤109
【分析】:二分答案。上界不能直接选择1e18,会爆long long。根据一棵树能完成需求的时间最小值不断降低时间。
【代码】:
#include <bits/stdc++.h> #define LL long long #define maxn 200005 using namespace std; LL a[maxn],h[maxn],S,L,mx; int n; bool check(LL x) { LL sum=0; for(int i=1; i<=n; i++) if(x &&log(a[i])+log(x)>log((max(S,L)))) return 1; for(int i=1; i<=n; i++) { LL now = h[i]+a[i]*x; if(now>=L) sum+=now; if(sum>=S) return 1; } return 0; } int main() { cin>>n>>S>>L; for(int i=1;i<=n;i++) cin>>h[i]; for(int i=1;i<=n;i++) cin>>a[i],mx=max(mx,max(L,S)/a[i]); LL l=0,r=mx,ans=0; while(l<=r) { LL mid=(l+r)>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } cout<<ans<<endl; }
#include<iostream> #include<set> #include<cstring> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef unsigned long long ll; ll h[2000010],a[2000010]; ll sum; int main() { ll n,S,L,i,j,l,r,m; while(cin>>n>>S>>L) { l=0;r=1e18;m=(l+r)/2; for(i=0;i<n;i++) scanf("%d",&h[i]); for(i=0;i<n;i++) scanf("%d",&a[i]); while(l<r) { sum=0; for(i=0;i<n;i++) { ll x=h[i]+m*a[i]; if(x>=L) sum+=x; if(sum>=S) break; } if(sum>=S) { r=m; } else { l=m+1; } m=(l+r)/2; } cout<<m<<"\n"; } return 0; }
#include <cstdio> #include <algorithm> using namespace std; typedef long long ll; int n; ll s,l; ll h[200100],a[200100]; int check(ll mid) { ll sum=0; for(int i=1;i<=n;i++) { if(h[i]+a[i]*mid>=l) sum+=(h[i]+a[i]*mid); if(sum>=s) return 1; } return 0; } ll maxx; 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]),maxx=max(maxx,a[i]); ll l=0,r=1e18/maxx,mid,ans=0; while(l<=r) { mid=(l+r)/2; if(check(mid)) r=mid-1,ans=mid; else l=mid+1; } printf("%lld",ans); }
以上是关于Code+ B 汀博尔二分答案的主要内容,如果未能解决你的问题,请参考以下文章