The studio «Lodka Gaming» is engaged in advertising of their new game «.C.O.N.T.E.S.T: Unexpected Behaviour». The studio’s marketer is planning to communicate with n videobloggers one by one (in the predetermined order, starting from the 1-st and ending with the n-th), offering them to record a video review on the game. All people are different and videobloggers are as well, therefore the i-th videoblogger will record a review in two cases: either he is interested in this game, or there are already at least ai video reviews on this game.
The studio wants to have at least m video reviews in the Internet. The game designer of «Lodka Gaming» understands these video reviews possibly would not appear by themselves, so he wants to convince some video bloggers that they are actually interested in this game. Which minimal number of videobloggers are needed to be convinced?
Input
The first line contains two integers n and m (1 ≤ n ≤ 200000, 1 ≤ m ≤ n) — the number of videobloggers and the required number of video reviews.
The second line contains n integers ai (0 ≤ ai ≤ 200000) — the minimal number of video reviews that should appear in the Internet so that the i-th videoblogger will record a review in case he is not interested in the game.
Output
Output a single integer — the minimal number of videobloggers who have to be convinced to record a video review on the game in order to achieve at least m total video reviews in the Internet.
Examples
Input
7 4
2 1 3 3 4 2 3
Output
1
Input
7 4
2 1 3 3 4 3 2
Output
2
题意:一家公司想让n个人给他们的产品评论,所以依次去找这n个人,第i个人会评论当且仅当已经有ai个人评论或他确实对这个产品感兴趣,但是这n个人都不对这个产品感兴趣,问这个公司至少要说服几个人对该产品该兴趣才能至少收到m个人的评论
假如你要强迫人肯定要强迫最前边的,因为说服一个人对评论数贡献为1,而提早做贡献可以带来更多的贡献
对于这种情况,有种强大的方法:二分(二分要强迫的人数)
二分的好处就是简化复杂度,用假设的已知代替未知
对于求一个最多或最少的问题,通常可以用二分来简单地解决
像这题,用二分得到确切的强迫次数,那么就可以直接从前往后遍历了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2e5+10;
int a[maxn];
int n,m;
bool check(int k)
{
int ans = 0; //记录评论数
int i;
for(i=0; i<n; i++)
{
if(a[i]<=ans)
ans++;
else if(k)
{
ans++; //有强迫名额的话优先强迫
k--;
}
if(ans==m)
return true;
}
return false;
}
int main()
{
cin>>n>>m;
int i;
for(i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
int l = 0;
int r = m;
int ans;
while(l<=r)
{
int mid = (l+r)>>1;
if(check(mid)) // 如果强迫mid个人可以满足条件,
//就二分减少强迫的人数,否则增加
{
r = mid-1;
ans = mid;
}
else
{
l = mid+1;
}
}
printf("%d\n",min(m,ans)); //若强迫人数大于m,取m
return 0;
}