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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a.at(i);
  }

  int l = 0;
  int r = 1e9; // 指数表記 1 * 10**9

  // ### 二分探索
  //
  //     f(x) = 一番長い丸太を x 以下にできるかどうか
  // --> 全部を x 以下にするために切る回数 <= K であるかどうか
  while (r - l > 1) {
    // 真ん中あたりの座標をとる
    int x = (l + r) / 2;

    // &: 参照で変数をキャプチャ
    //
    // ### データ例1
    // * n = 7
    // * a = [1, 2, 3, 4, 5, 6, 7]
    //
    // これより x = (7+0) / 2 = 3
    // 丸太の長さを3以下にするために必要な、丸太の切断回数は以下で算出する。
    //
    // * 丸太:     1 2 3 4 5 6 7
    // * 切断回数: 0 0 0 1 1 1 2
    // --> (a[i]-1) / 2
    //
    // これより、x=3 の時の切断回数は 5 となる。
    //
    // ### データ例2
    // * n = 2
    // * k = 3
    // * a = [7, 9]
    //
    // ##### ループ1回目
    // * x = (0+1e9) / 2 = 5e8
    // * now = (7-1) / 5e8 + (9-1) / 5e8;
    //       = 0
    // * f(5e8) --> true
    //   * 2本の丸太を 5e8 以下の長さにすることは k=3 以下の切断回数で実現できる
    //   * これより x >= 5e8 && x <= 1e9 も同様に実現できる
    // * r = 5e8 に狭めて、二分探索を継続する
    //
    // ##### ループ2回目
    // * x = (0+5e8) / 2 = 25e7
    // * now = (7-1) / 25e7 + (9-1) / 25e7;
    //       = 0
    // * f(25e7) --> true
    // * r = 25e7
    //
    // ##### ループn回目
    // * 3回目 ... x = 125,000,000
    // * 4回目 ... x = 62,500,000
    // * 5回目 ... x = 15,625,000
    // (省略)
    // * 25回目 ... x = 29
    // * 26回目 ... x = 14
    //
    // ##### ループ27回目
    // * x = (0+14) / 2 = 7
    // * now = (7-1) / 7 + (9-1) / 7 = 1
    // * f(7) --> true
    // * r = 7
    //
    // ##### ループ28回目
    // * x = (0+7) / 2 = 3
    // * now = (7-1) / 3 + (9-1) / 3
    //       = 2 + 2
    //       = 4
    // * f(3) --> false
    // * l = 3
    //
    // ##### ループ29回目
    // * x = (3+7) / 2 = 5
    // * now = (7-1) / 5 + (9-1) / 5
    //       = 1 + 1
    //       = 2
    // * f(5) --> true
    // * r = 5
    //
    // ##### ループ30回目
    // * x = (3+5) / 2 = 4
    // * now = (7-1) / 4 + (9-1) / 4
    //       = 1 + 2
    //       = 3
    // * f(4) --> true
    // * r = 4
    //
    // r=4, l=3 より、r-l > 1 を満たさなくなったため、while ループを終了する
    //
    auto f = [&](int x) {
      ll now = 0;
      for (int i = 0; i < n; i++) {
        now += (a.at(i) - 1) / x;
      }
      return (now <= k);
    };
    if (f(x)) {
      r = x;
    } else {
      l = x;
    }
  }

  cout << r << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct Log {
  double length, division_num;
  double split_length;
  Log(int l) {
    length = l;
    division_num = 1;
    split_length = length / division_num;
  }

  bool operator<(const Log &right) const {
    return split_length < right.split_length;
  }

  void divide() {
    division_num++;
    split_length = length / division_num;
  }
};

int main() {
  int N, K;
  cin >> N >> K;
  vector<Log> A;

  for (int i = 0; i < N; i++) {
    int length;
    cin >> length;
    Log log(length);
    A.push_back(log);
  }

  while (K > 0) {
    sort(A.rbegin(), A.rend());
    A.at(0).divide();
    K--;
  }

  sort(A.rbegin(), A.rend());
  cout << (ll)ceil(A.at(0).split_length) << endl;
  return 0;
}