L-Flowers【2019沈阳】【二分答案】

Recently Jack becomes much more romantic. He would like to prepare several bunches of flowers.

Each bunch of flowers must have exactly M flowers. As Jack does not want to be boring, he hopes that flowers in the same bunch are all different species. Now there are N species of flowers in the flower shop, and the number of the i-th species of flower is a​i​​. Now Jack would like to know how many bunches of flowers he can prepare at most.

(Flowers are used to propose.)

Input

The first line contains an integer T (1≤T≤10) --- the number of test cases.

In the first line of each test case, there are two integers N, M (1≤N,M≤300000) --- the number of flowers' species and the number of flowers in a bunch.

In the second line of each test case, there are N integers --- the i-th integer indicates a​i​​ (1≤a​i​​≤10​9​​), the number of i-th species' flowers.

Output

For each test case, output one integer in one line --- the answer of the corresponding test case.


题目链接

邀请码:ae17b8c95ce5aac5

  题意:有N朵花,每朵花有a[i]个,现在有桶,每个桶至少要放M种不同的花,问最多可以有几个桶?

  思路:其实问题可以变成“短板效应”,怎么说呢?我们现在假设有X个桶,那么对于N朵花,如果花的数量a[i]是大于等于X的,那么最多也就是用其中X朵,如果小于X的,那么每朵花都可以被用上,现在呢,我们只要去看能用上的花的数量和X*M进行比较,来作为二分答案的判断标准。

 呜呜呜,想来难受,比赛的时候用了特判的方式,也不知道是不是正解,总之过了,深刻记得287分钟A的,却与奖牌无缘了呜呜呜,难受……

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 3e5 + 7;
int N;
ll a[maxN], M;
inline bool check(ll lim)
{
    ll sum = 0;
    for(int i=1; i<=N; i++) sum += min(a[i], lim);
    return sum >= lim * M;
}
int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        scanf("%d%lld", &N, &M);
        ll sum = 0;
        for(int i=1; i<=N; i++) { scanf("%lld", &a[i]); sum += a[i]; }
        ll L = 0, R = sum / M, mid, ans = 0;
        while(L <= R)
        {
            mid = (L + R) >> 1LL;
            if(check(mid))
            {
                L = mid + 1;
                ans = mid;
            }
            else R = mid - 1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值