Educational Codeforces Round 141 (Rated for Div. 2) C

70 阅读2分钟

You are participating in Yet Another Tournament. There are n+1 participants: you and n other opponents, numbered from 1 to n.

Each two participants will play against each other exactly once. If the opponent i plays against the opponent j, he wins if and only if i>j.

When the opponent i plays against you, everything becomes a little bit complicated. In order to get a win against opponent i, you need to prepare for the match for at least ai minutes — otherwise, you lose to that opponent.

You have m minutes in total to prepare for matches, but you can prepare for only one match at one moment. In other words, if you want to win against opponents p1,p2,…,pk, you need to spend ap1+ap2+⋯+apk minutes for preparation — and if this number is greater than m, you cannot achieve a win against all of these opponents at the same time.

The final place of each contestant is equal to the number of contestants with strictly more wins + 1. For example, if 3 contestants have 5 wins each, 1 contestant has 3 wins and 2 contestants have 1 win each, then the first 3 participants will get the 1-st place, the fourth one gets the 4-th place and two last ones get the 5-th place.

Calculate the minimum possible place (lower is better) you can achieve if you can't prepare for the matches more than m minutes in total.

Input

The first line contains a single integer t (1≤t≤104) — the number of test cases.

The first line of each test case contains two integers n and m (1≤n≤5⋅105; 0≤m≤∑i=1nai) — the number of your opponents and the total time you have for preparation.

The second line of each test case contains n integers a1,a2,…,an (0≤ai≤1000), where ai is the time you need to prepare in order to win against the i-th opponent.

It's guaranteed that the total sum of n over all test cases doesn't exceed 5⋅105.

Output

For each test case, print the minimum possible place you can take if you can prepare for the matches no more than m minutes in total.

思路: 二分答案

或者赢n - mid + 1场

或者赢n - mid场, 但是赢了原来的第n - mid + 1名

代码:

bool check(int mid)

{

    if (s[n - mid + 1] <= m) return true;

    if (s[n - mid] > m) return false;

    if (pos[n - mid + 1] <= n - mid) return true;

    if ((mid == n ? 0 : s[n - mid - 1]) <= m - p[pos[n - mid + 1]].first)

    return true;

    return false;

}

int main(){

    cin.tie(0);

    cout.tie(0);

    ios::sync_with_stdio(0);

    int T;

    cin >> T;

    while(T--){

        cin >> n >> m;

        for(int i = 1; i <= n; i++){

            int x;

            cin >> x;

            p[i] = {x, i};

        }

        sort(p + 1, p + n + 1);

        for(int i = 1; i <= n; i++){

            s[i] = s[i - 1] + p[i].first;

            pos[p[i].second] = i;

        }

        int l = 1, r = n + 1;

        while(l < r){

            int mid = (l + r) / 2;

            if (check(mid)) r = mid;

            else l = mid + 1;

        }

        cout << r << '\n';

    }

}