当前位置: 代码迷 >> 综合 >> 2019 ICPC沈阳 Flowers
  详细解决方案

2019 ICPC沈阳 Flowers

热度:62   发布时间:2024-02-25 01:04:00.0

题意: 给定nnn种花,第iii种有aia_iai?朵,一束花由mmm朵互不相同种类的花组成,问最多可以组成多少束花。
数据范围:1≤n,m≤3×105,1≤ai≤1091\leq n,m\leq 3\times10^5,1\leq a_i\leq 10^91n,m3×105,1ai?109

题解: 二分答案,设当前答案为xxx,判断答案是否合法,合法则真实答案至少为xxx,否则真实答案至多为x?1x-1x?1。判断条件是每种花取ci=min(x,ai)c_i=min(x,a_i)ci?=min(x,ai?),最后判断sum≥∑cisum \geq \sum c_isumci?是否成立即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<cmath>
using namespace std;typedef long long ll;template<typename T>
inline T Read(){
    T s = 0, f = 1; char ch = getchar();while(!isdigit(ch)) {
    if(ch == '-') f = -1; ch = getchar();}while(isdigit(ch)) {
    s = (s << 3) + (s << 1) + ch - '0'; ch = getchar();}return s * f;
}#define read() Read<int>()
#define readl() Read<long long>()const int N = 3e5 + 10;
int a[N];
int n, m;bool check(int x) {
    ll sum = 0;for(int i = 1; i <= n; i++) sum += min(x, a[i]);return sum >= 1ll * x * m;
}void solve() {
    n = read(), m = read();ll sum = 0;for(int i = 1; i <= n; i++) a[i] = read(), sum += a[i];int l = 0, r = sum / m;while(l < r) {
    int mid = l + r + 1 >> 1;if(check(mid)) l = mid;else r = mid - 1;}printf("%d\n", l);
}int main()
{
    int T = 1;T = read();for(int i = 1; i <= T; ++i) {
    solve();}return 0;
}