Problem p02598 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
#define int long long

bool isprime(int n) {
  double rootn = sqrt(n);
  if (n < 2) {
    return false;
  } else if (n == 2) {
    return true;
  } else if (n % 2 == 0) {
    return false;
  } else {
    for (int i = 3; i <= rootn; i += 2) {
      if (n % i == 0) {
        return false;
      }
    }
    return true;
  }
}

// 空のベクトルを二つ渡す。N (>=2) 以下の素数を primes に順番に入れる。
void prime_vectors(int N, vector<int> &primes, vector<bool> &is_prime) {
  primes = {};
  is_prime = {};
  for (int i = 0; i <= N; i++) {
    is_prime.push_back(true);
  }

  primes.push_back(2);
  for (int j = 4; j <= N; j += 2) {
    is_prime[j] = false;
  }

  int i;
  for (i = 3; i * i <= N; i += 2) {
    if (!is_prime[i])
      continue;
    primes.push_back(i);
    for (int j = 2 * i; j <= N; j += i) {
      is_prime[j] = false;
    }
  }

  for (; i <= N; i += 2) {
    if (is_prime[i]) {
      primes.push_back(i);
    }
  }
}

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int N, K;
  cin >> N >> K;
  vector<int> A(N);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }

  // K 回以下の切断で丸太をすべて x 以下の長さに分割できるか
  auto f = [&](int x) {
    int ans = 0;
    for (int i = 0; i < N; i++) {
      ans += (A[i] + x - 1) / x - 1;
    }
    return ans <= K;
  };

  // 解で二分探索
  int l = 0, r = 1e9;
  while (r - l > 1) {
    int m = (l + r) / 2;
    if (f(m)) {
      r = m;
    } else {
      l = m;
    }
  }
  cout << r << endl;

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long

bool isprime(int n) {
  double rootn = sqrt(n);
  if (n < 2) {
    return false;
  } else if (n == 2) {
    return true;
  } else if (n % 2 == 0) {
    return false;
  } else {
    for (int i = 3; i <= rootn; i += 2) {
      if (n % i == 0) {
        return false;
      }
    }
    return true;
  }
}

// 空のベクトルを二つ渡す。N (>=2) 以下の素数を primes に順番に入れる。
void prime_vectors(int N, vector<int> &primes, vector<bool> &is_prime) {
  primes = {};
  is_prime = {};
  for (int i = 0; i <= N; i++) {
    is_prime.push_back(true);
  }

  primes.push_back(2);
  for (int j = 4; j <= N; j += 2) {
    is_prime[j] = false;
  }

  int i;
  for (i = 3; i * i <= N; i += 2) {
    if (!is_prime[i])
      continue;
    primes.push_back(i);
    for (int j = 2 * i; j <= N; j += i) {
      is_prime[j] = false;
    }
  }

  for (; i <= N; i += 2) {
    if (is_prime[i]) {
      primes.push_back(i);
    }
  }
}

signed main() {
  // cout << fixed << setprecision(10) << flush;

  int N, K;
  cin >> N >> K;
  set<tuple<double, int, int>> A;
  for (int i = 0; i < N; i++) {
    int a;
    cin >> a;
    A.insert(make_tuple(a, -a, -1));
  }

  // だいたい平均ぐらい
  for (int i = 0; i < K; i++) {
    auto it = A.end();
    it--;
    double aaa = get<0>(*it);
    int aa = get<1>(*it);
    int ii = get<2>(*it);
    if (A.size() > 1) {
      it--;
      double bbb = get<0>(*it);
      if (ii > (-1) * (int)(-aa / bbb) && K - i - 1 > ii + (int)(-aa / bbb)) {
        ii = (-1) * (int)(-aa / bbb);
        i += ii + (int)(-aa / bbb);
      }
    }

    double new_a = 1.0 * aa / (ii - 1);
    int new_i = ii - 1;
    it++;
    A.erase(it);
    A.insert(make_tuple(new_a, aa, new_i));
  }

  auto itr = A.end();
  itr--;
  double max_a = 1.0 * get<1>(*itr) / get<2>(*itr);
  int a = ceil(max_a);

  cout << a << endl;

  return 0;
}