M - xzlnb!! (二分降低时间复杂度)

http://codeforces.com/gym/101755/problem/K

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个人,需要m个人评论,对这个游戏都没有兴趣,所以最少需要ai个人评论,才评论。问最少需要多少个人评论。

思路就是通过二分降低复杂度

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include <stdio.h>
#include <string.h>
using namespace std;
const int N = 500009 ;
int a[200009];
int n , p ;

int check(int k)//代表可说服人数
{
    int ans = 0 ;//
    for(int i = 0 ; i < n ; i++)
    {
        if(ans >= a[i])
        {
            ans++;
        }
        else if(k)//不符合,能说服就说服
        {
            k--;
            ans++ ;
        }
        if(ans == p)
            return 1 ;
    }
    return 0 ;
}


int main()
{

    while(~scanf("%d%d" , &n ,&p))
    {
        for(int i = 0 ; i < n ; i ++)
        {
            scanf("%d"
                  
                   , &a[i]);
        }
        int l = 0 , r = p , mid , ans = p ;
        while(l <= r)
        {
            mid = (l + r) / 2 ;
            if(check(mid))//如果答案是有mid个人评论了,判断是否符合题意
            {
                r = mid - 1 ;//如果mid个人评论符合题意,区间右区间就左移,继续找最小答案
                ans = mid ;
            }
            else
                l = mid + 1 ;
        }
        cout << ans << endl ;
    }


    return 0 ;
}


猜你喜欢

转载自www.cnblogs.com/nonames/p/11272608.html