Problem p02598 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define err(args...)                                                           \\
  {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream &operator>>(istream &is, vector<T> &a) {
  for (T &x : a) {
    is >> x;
  }
  return is;
}
template <typename X, typename Y>
istream &operator>>(istream &is, pair<X, Y> &p) {
  return is >> p.first >> p.second;
}
template <typename T, typename Can>
T bsearch(T L, T R, const Can &can, bool left_feasible = true) {
  static_assert(is_convertible<decltype(can), function<bool(T)>>::value,
                "can must be bool(T)");
  T &feasible = left_feasible ? L : R;
  T &infeasible = left_feasible ? R : L;
  while (R - L > 1) {
    T M = L + (R - L) / 2;
    (can(M) ? feasible : infeasible) = M;
  }
  return feasible;
}
ll ceildiv(ll x, ll y) { return (x + y - 1) / y; }
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  cin >> a;
  cout << bsearch(
              0, *max_element(a.begin(), a.end()),
              [&](int max_piece) {
                ll needed_cuts = 0;
                for (int ai : a) {
                  needed_cuts += ceildiv(ai, max_piece) - 1;
                }
                return needed_cuts <= k;
              },
              false)
       << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define err(args...)                                                           \\
  {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream &operator>>(istream &is, vector<T> &a) {
  for (T &x : a) {
    is >> x;
  }
  return is;
}
template <typename X, typename Y>
istream &operator>>(istream &is, pair<X, Y> &p) {
  return is >> p.first >> p.second;
}
template <typename T, typename Can>
T bsearch(T L, T R, const Can &can, bool left_feasible = true) {
  static_assert(is_convertible<decltype(can), function<bool(T)>>::value,
                "can must be bool(T)");
  T &feasible = left_feasible ? L : R;
  T &infeasible = left_feasible ? R : L;
  while (R - L > 1) {
    T M = L + (R - L) / 2;
    (can(M) ? feasible : infeasible) = M;
  }
  return feasible;
}
ll ceildiv(ll x, ll y) { return (x + y - 1) / y; }
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  cin >> a;
  cout << bsearch(
              0, *max_element(a.begin(), a.end()),
              [&](int max_piece) {
                ll needed_cuts = 0;
                for (int ai : a) {
                  needed_cuts += bsearch(
                      -1, ai - 1,
                      [&](int cuts) {
                        return ceildiv(ai, cuts + 1) <= max_piece;
                      },
                      false);
                }
                return needed_cuts <= k;
              },
              false)
       << endl;
  return 0;
}