Codeforces Round #350 (Div. 2) D2 - Magic Powder - 2

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种原料每种需要多少个才能做一个蛋糕,再给出当前每种原料的库存,最后给你魔法值可以拿来当做任何一种原料,问你最多做几个。

分析:

数据比较大,二分一下就好了。本来水题没什么记录的必要性,这里写二分的时候写二逼了,mid写在前面导致二分0,1时出现bug。D1题里面数据比较弱没触发这个bug,D2里面的第138组数据触发了,debug半天没想到是二分写错了。引以为戒。

再写详细一点,其实就是找出n种原料中,每种原料的库存能够做几份蛋糕。题目用数组a和b表示,那就新建个数组c=b/a来存每种原料的倍数。二分的时候在数组c的最大值与最小值内二分即可,如果魔法值还有剩下,此时二分完原料已经为空,直接凭空做蛋糕即可。这里也可以直接无脑二分,代码量可以少很多,即二分的范围从0-1e9,最终二分的结果当然是正确的,但这样感觉有些暴力,就优化了一些。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <fstream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const int N=100005;
const int mod=1e9+7;

int a[N],b[N],c[N],n,k;

long long solve(int t) {
    long long sum=0,temp;
    for (int i=1; i<=n; i++) {
        temp=(long long)(t*a[i]-b[i]);
        if (temp>0) {
            sum+=temp;
        }
    }
    return sum;
}

int main() {
    long long sum;
    while (cin>>n>>k) {
        sum=0;
        for (int i=1; i<=n; i++) {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        int minn=INF,maxx=0;
        for (int i=1; i<=n; i++) {
            scanf("%d",&b[i]);
            c[i]=b[i]/a[i];
            minn=min(c[i],minn);
            maxx=max(maxx,c[i]);
        }
        int left=minn,right=maxx,mid=left+(right-left)/2,flag = minn+1;
        long long temp;
        temp=solve(maxx+1);
        if (temp<=k) {
            right=minn;
            flag=maxx+1;
        }
        while (left<right) {
            temp=solve(mid);
            if (temp==k) {
                break;
            } else if (temp>k) right=mid;
            else left=mid+1;
            mid=left+(right-left)/2;
            flag=mid;
        }
        if (solve(flag)>k) {
            flag--;
        }
        k-=solve(flag);
        int s=flag;
        if (k>sum) {
            s+=k/sum;
        }
        cout<<s<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值