http://codeforces.com/contest/670/problem/D2
简单的二分,二分所有可以做的饼干数,然后遍历就可以啦
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long LL;
#define N 210000
#define INF 0x3f3f3f3f
#define met(a, b) memset (a, b, sizeof(a))
struct node
{
LL one, sum;///做一个饼干需要的材料和已经有的材料
LL num, need;///当前材料可以做的饼干数和做剩下的材料
}p[N];
bool cmp (node a, node b)
{
return a.num < b.num;
}
LL n, k, L, R;
LL Search ()
{
LL l = L, r = R, maxn = 0;
while (l<=r)
{
LL mid = (l+r)/2, S = 0;
for (int i=0; i<n; i++)
{
if (p[i].num < mid)
{
S += p[i].one-p[i].need;
if (mid>p[i].num)
S += (mid-1-p[i].num)*p[i].one;
if (S > k) break;///第一次没加上这个判断条件WA在第128组测试数据上了
}
}
if (S <= k)
{
maxn = max (maxn, mid);
l = mid+1;
}
else r = mid-1;
}
return maxn;
}
void Solve ()
{
sort (p, p+n, cmp);
L = R = p[0].num;
for (int i=0; i<n; i++)
R = max (R, (k+p[i].need)/p[i].one+p[i].num);
LL ans = Search();
printf ("%I64d\n", ans);
}
int main ()
{
while (scanf ("%I64d %I64d", &n, &k) != EOF)
{
met (p, 0);
for (int i=0; i<n; i++)
scanf ("%I64d", &p[i].one);
for (int i=0; i<n; i++)
{
scanf ("%I64d", &p[i].sum);
p[i].num = p[i].sum / p[i].one;
p[i].need = p[i].sum % p[i].one;
}
Solve ();
}
return 0;
}