Codeforces Round #350 (Div. 2) D1,D2Magic Powder(二分)

D2. Magic Powder - 2
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

The term of this problem is the same as the previous one, the only exception — increased restrictions.

Input

The first line contains two positive integers n and k (1 ≤ n ≤ 100 000, 1 ≤ k ≤ 109) — the number of ingredients and the number of grams of the magic powder.

The second line contains the sequence a1, a2, ..., an (1 ≤ ai ≤ 109), where the i-th number is equal to the number of grams of the i-th ingredient, needed to bake one cookie.

The third line contains the sequence b1, b2, ..., bn (1 ≤ bi ≤ 109), where the i-th number is equal to the number of grams of the i-th ingredient, which Apollinaria has.

Output

Print the maximum number of cookies, which Apollinaria will be able to bake using the ingredients that she has and the magic powder.

Examples
input
1 1000000000
1
1000000000
output
2000000000
input
10 1
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
1 1 1 1 1 1 1 1 1 1
output
0
input
3 1
2 1 4
11 3 16
output
4
input
4 3
4 3 5 6
11 12 14 20
output
3
 
         
 
         
 
         

题意:要做一到菜需要n种原料,每种原料需要ai克。现在每种原料有bi克,并且有k克魔法原料,每克魔法原料可以变为1克的任意原料。问你最多能做多少道菜。

解法:D1题复杂度不是很高,我们可以枚举可能做的菜的道数。n,k,ai,bi均小于1000,即最的菜数为2000.枚举的复杂度为1000*n<10^6.对于D2我们也可以枚举做得菜的道数枚举范围1-2000000000,如果继续按D1题的话就会超时。所以我们需要一个n*lgn的算法。然后由于枚举是个有序的连续区间,这要我们就会很容易的想到二分的思想。二分枚举的区间,复杂度就变为lg(2000000000)*n<64*100000.

二分代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll __int64
ll l,r,mid;
ll n,k;
ll a[100080],b[100080];
bool isans(ll temp)
{
    ll ps=k;
    for(int i=0;i<n;i++)
    {
            if(b[i]>=a[i]*temp) continue ;
            else
            {
                ps=ps-a[i]*temp+b[i];
            }
            if(ps<0) return 0;
    }
    return 1;
}
int main()
{
    ll ans=0;
    scanf("%I64d%I64d",&n,&k);
    for(int i=0;i<n;i++)
    {
         scanf("%I64d",&a[i]);
    }
    for(int i=0;i<n;i++)
    {
         scanf("%I64d",&b[i]);
    }
    l=0;
    r=2000000009;
    while(l<r)
    {
        mid=l+(r-l)/2;
        if(!isans(mid))
        {
            r=mid;
        }
        else
        {
            ans=max(mid,ans);
            l=mid+1;
        }
    }
    printf("%I64d\n",ans);
}

你可能感兴趣的:(codeforces,二分)