Coffee_and_Coursework二分答案+贪心

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

Polycarp has to write a coursework. The coursework consists of mm pages.

Polycarp also has nn cups of coffee. The coffee in the ii-th cup Polycarp has aiai 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 kk cups of coffee during this day and caffeine dosages of cups Polycarp drink during this day are ai1,ai2,…,aikai1,ai2,…,aik. Then the first cup he drinks gives him energy to write ai1ai1 pages of coursework, the second cup gives him energy to write max(0,ai2−1)max(0,ai2−1) pages, the third cup gives him energy to write max(0,ai3−2)max(0,ai3−2) pages, …, the kk-th cup gives him energy to write max(0,aik−k+1)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 nn and mm (1≤n≤2⋅1051≤n≤2⋅105, 1≤m≤1091≤m≤109) — the number of cups of coffee and the number of pages in the coursework.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109), where aiai is the caffeine dosage of coffee in the ii-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.

Examples
inputCopy
5 8
2 3 1 1 2
outputCopy
4
inputCopy
7 10
1 3 4 2 1 4 2
outputCopy
2
inputCopy
5 15
5 5 5 5 5
outputCopy
1
inputCopy
5 16
5 5 5 5 5
outputCopy
2
inputCopy
5 26
5 5 5 5 5
outputCopy
-1
Note
In the first example Polycarp can drink fourth cup during first day (and write 11 page), first and second cups during second day (and write 2+(3−1)=42+(3−1)=4 pages), fifth cup during the third day (and write 22 pages) and third cup during the fourth day (and write 11 page) so the answer is 44. It is obvious that there is no way to write the coursework in three or less days.

扫描二维码关注公众号,回复: 6106464 查看本文章

In the second example Polycarp can drink third, fourth and second cups during first day (and write 4+(2−1)+(3−2)=64+(2−1)+(3−2)=6 pages) and sixth cup during second day (and write 44 pages) so the answer is 22. It is obvious that Polycarp cannot write the whole coursework in one day in this test.

In the third example Polycarp can drink all cups of coffee during first day and write 5+(5−1)+(5−2)+(5−3)+(5−4)=155+(5−1)+(5−2)+(5−3)+(5−4)=15 pages of coursework.

In the fourth example Polycarp cannot drink all cups during first day and should drink one of them during the second day. So during first day he will write 5+(5−1)+(5−2)+(5−3)=145+(5−1)+(5−2)+(5−3)=14 pages of coursework and during second day he will write 55 pages of coursework. This is enough to complete it.

In the fifth example Polycarp cannot write the whole coursework at all, even if he will drink one cup of coffee during each day, so the answer is -1.

思路:
这道题有两个版本 差别就是数据规模 规模小的暴力就可以 规模大的就得需要二分了 这道题其实是一个典型的二分答案 利用二分查找去寻找答案 然后check函数用找到的 ”答案“ 去检测 对于这道题的check函数 我们首先要排序 因为最小值是零 我们把大的数减到零还不如让小的数去减相同的数 这样所得到的值才是最优的

注意一定要把数据开到 long long 否则会WA在25个测试点
AC代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
long long m,n;
long long a[10000010];
int tmp(long long a,long long b)
{
	return a>b;
}
bool check(long long tmp)
{
	long long sum=0;
	for(long long i=1,t=0;i<=m;i++)
	{
		sum+=std::max((long long)0,(a[i]-t));
		//相当于把这些数往每天的第一个去填充 以此类推 
		if(i%tmp==0) t++;
	}
	return sum>=n;
}
int main()
{
	long long sum=0;
	scanf("%lld %lld",&m,&n);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",a+i);
		sum+=a[i]; 
	}
	sort(a+1,a+m+1,tmp); 
	if(sum<n)
	{
		printf("-1");
		return 0;
	}
	int l=1,r=m+1,mid;
	while(l<r)	
	{
		mid=(l+r)/2;
		if(check(mid))	r=mid;
		else	l=mid+1; 
	}
	printf("%d",l);
	return 0;
 }

猜你喜欢

转载自blog.csdn.net/weixin_43705457/article/details/89047617