cf Coffee and Coursework (Hard Version) 二分题

探讨在有限咖啡因条件下,通过优化算法快速完成课程作业的策略。使用二分法寻找最小工作天数,确保在给定的咖啡因剂量下,最大化每日写作页数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D2. Coffee and Coursework (Hard Version)
time limit per test
2.5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

The only difference between easy and hard versions is the constraints.

Polycarp has to write a coursework. The coursework consists of m

pages.

Polycarp also has n
cups of coffee. The coffee in the i-th cup Polycarp has ai

caffeine in it. Polycarp can drink some cups of coffee (each one no more than once). He can drink cups in any order. Polycarp drinks each cup instantly and completely (i.e. he cannot split any cup into several days).

Surely, courseworks are not being written in a single day (in a perfect world of Berland, at least).

Let’s consider some day of Polycarp’s work. Consider Polycarp drinks k
cups of coffee during this day and caffeine dosages of cups Polycarp drink during this day are ai1,ai2,…,aik. Then the first cup he drinks gives him energy to write ai1 pages of coursework, the second cup gives him energy to write max(0,ai2−1) pages, the third cup gives him energy to write max(0,ai3−2) pages, …, the k-th cup gives him energy to write max(0,aik−k+1)

pages.

If Polycarp doesn’t drink coffee during some day, he cannot write coursework at all that day.

Polycarp has to finish his coursework as soon as possible (spend the minimum number of days to do it). Your task is to find out this number of days or say that it is impossible.
Input

The first line of the input contains two integers n
and m (1≤n≤2⋅105, 1≤m≤109

) — the number of cups of coffee and the number of pages in the coursework.

The second line of the input contains n
integers a1,a2,…,an (1≤ai≤109), where ai is the caffeine dosage of coffee in the i

-th cup.
Output

If it is impossible to write the coursework, print -1. Otherwise print the minimum number of days Polycarp needs to do it.
天数并不需要从第一天一天天的往上加,而可以用二分法来算

#include <bits/stdc++.h>
using namespace std;
const int max_n = 200222, inf = 1000111222;
int n, m, a[max_n];
bool check(int cnt) 
{
    long long sum = 0;
    int last = 1;
    for (int i = 0; i < n; ++i) 
    {
        if (i % cnt == 0) --last;
        if (a[i] + last > 0) sum += (a[i] + last);
    }
    return sum >= m;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; ++i) 
        scanf("%d", &a[i]);
    sort(a, a + n);
    reverse(a, a + n);
    int l = 0, r = n + 1;
    while (r - l > 1)
    {
        int mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    if (r > n) puts("-1");
    else printf("%d\n", r);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值