我们考虑朴素算法,假设Max为给出木条的最大长度,直接枚举长度 0~Max,找到符合情况的最大值即可,由于最大长度可以为1e9,复杂度最差为O(1e9n)显然不行,观察发现,如果对于裁剪出长度为x的木条最多能凑出sum根,那么裁剪x+1长度的木条,肯定不会得到sum+1根,很明显,具有单调性,我们就能考虑二分。就像猜数字一个,每次猜一个数,判断能不能,如果符合,就可以往大的猜,如果不可以,就缩小。由于木条最大长度是1e9,所以二分复杂度为O(log1e9),对于判断,只需要遍历一遍全部木条即可,复杂度为O(n),总复杂度为O(nlog1e9)。

#include <cstring>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <map>
#include<time.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int n,m,A[maxn];
bool check(ll m1) {
    if (m1==0) return true;
    ll cnt=0;
    for (int i=1; i<=n; i++) {
        cnt+=A[i]/m1;
    }
    return cnt>=m;
}
int main(){
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) {
        scanf("%d",&A[i]);
    }
    ll l=0,r=1e9;
    ll ans=0;
    while (l<=r) {
        ll m1=l+(r-l+1)/2;
        if (check(m1)) {
            l=m1+1;
            ans=m1;
        } else r=m1-1;
    }
    printf("%lld\n",ans);
    return 0;
}