Problem p03585 (C++)

Buggy submission (status: Runtime Error):

#if 1
#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cstdint>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

auto &in = std::cin;
auto &out = std::cout;

int32_t N;
int32_t A[40000];
int32_t B[40000];
int32_t C[40000];

std::pair<double, int32_t> zero_V[40000];
std::pair<double, int32_t> tmp_V[40000];
int32_t zero_V_pos[40000]; // i番目のzero_Vのindex

void func_xtoy(double X, std::pair<double, int32_t> (&res)[40000]) {
  for (size_t i = 0; i < N; i++) {
    res[i].first = double(C[i] - A[i] * X) / B[i];
    res[i].second = -zero_V_pos[i];
  }
  std::sort(res, res + N);
}
void func_ytox(double Y, std::pair<double, int32_t> (&res)[40000]) {
  for (size_t i = 0; i < N; i++) {
    res[i].first = double(C[i] - B[i] * Y) / A[i];
    res[i].second = -zero_V_pos[i];
  }
  std::sort(res, res + N);
}

template <typename FUNC>
// 区間[b,e)　でf(r)==trueとなる最大のrを探す
// predの条件：(f(i) == true && f(j) == false) ==> (i < j)
// 　　　　　　f(b) == true && f(e) == false
double binary_search_D(double b, double e, FUNC &&f) {
  for (size_t i = 0; i < 70; ++i) {
    auto mid = (b + e) / 2;
    if (f(mid)) {
      b = mid;
    } else {
      e = mid;
    }
  }
  return b;
}

inline constexpr uint32_t get_min2pow(uint32_t value, uint32_t work = 1) {
  return ((value <= work) ? (work) : (get_min2pow(value, work * 2)));
}

namespace BIT {
// [1, n]
int bit[40000 + 1], n; // nは2の累乗
int sum(int i) {
  int s = 0;
  while (i > 0) {
    s += bit[i];
    i -= i & -i;
  }
  return s;
}
void add(int i, int x) {
  while (i <= n) {
    bit[i] += x;
    i += i & -i;
  }
}
void init() {
  n = 1;
  while (n < N) {
    n *= 2;
  }
  for (int32_t i = 0; i <= n; i++) {
    bit[i] = 0;
  }
}
} // namespace BIT

int main() {
  using std::endl;
  in.sync_with_stdio(false);
  out.sync_with_stdio(false);
  in.tie(nullptr);
  out.tie(nullptr);

  in >> N;
  for (int32_t i = 0; i < N; i++) {
    in >> A[i] >> B[i] >> C[i];
  }

  // Xを求める！！！
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[i] = i;
  }
  func_xtoy(-1000000000.0, zero_V);
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[-zero_V[i].second] = i;
  }
  double X_RES = binary_search_D(-1000000000.0, +1000000000.0, [](double X) {
    func_xtoy(X, tmp_V);
    BIT::init();
    // 交差回数を求める
    int32_t conf = 0;
    int32_t min_ = 0;
    BIT::add((-tmp_V[0].second) + 1, 1);
    for (int32_t i = 1; i < N; i++) {
      conf += BIT::sum(N) - BIT::sum(-tmp_V[i].second);
      BIT::add((-tmp_V[i].second) + 1, 1);
    }
    return conf * 2 < (N * (N - 1) / 2);
  });

  // Yを求める！！！
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[i] = i;
  }
  func_ytox(-1000000000.0, zero_V);
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[-zero_V[i].second] = i;
  }
  double Y_RES = binary_search_D(-1000000000.0, +1000000000.0, [](double Y) {
    func_ytox(Y, tmp_V);
    BIT::init();
    // 交差回数を求める
    int32_t conf = 0;
    int32_t min_ = 0;
    BIT::add((-tmp_V[0].second) + 1, 1);
    for (int32_t i = 1; i < N; i++) {
      conf += BIT::sum(N) - BIT::sum(-tmp_V[i].second);
      BIT::add((-tmp_V[i].second) + 1, 1);
    }
    return conf * 2 < (N * (N - 1) / 2);
  });

  out << std::fixed << std::setprecision(19) << X_RES << ' ' << Y_RES << endl;

  return 0;
}
#endif


Fixed submission:

#if 1
#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cstdint>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

auto &in = std::cin;
auto &out = std::cout;

int32_t N;
int32_t A[40000];
int32_t B[40000];
int32_t C[40000];

std::pair<double, int32_t> zero_V[40000];
std::pair<double, int32_t> tmp_V[40000];
int32_t zero_V_pos[40000]; // i番目のzero_Vのindex

void func_xtoy(double X, std::pair<double, int32_t> (&res)[40000]) {
  for (size_t i = 0; i < N; i++) {
    res[i].first = double(C[i] - A[i] * X) / B[i];
    res[i].second = -zero_V_pos[i];
  }
  std::sort(res, res + N);
}
void func_ytox(double Y, std::pair<double, int32_t> (&res)[40000]) {
  for (size_t i = 0; i < N; i++) {
    res[i].first = double(C[i] - B[i] * Y) / A[i];
    res[i].second = -zero_V_pos[i];
  }
  std::sort(res, res + N);
}

template <typename FUNC>
// 区間[b,e)　でf(r)==trueとなる最大のrを探す
// predの条件：(f(i) == true && f(j) == false) ==> (i < j)
// 　　　　　　f(b) == true && f(e) == false
double binary_search_D(double b, double e, FUNC &&f) {
  for (size_t i = 0; i < 70; ++i) {
    auto mid = (b + e) / 2;
    if (f(mid)) {
      b = mid;
    } else {
      e = mid;
    }
  }
  return b;
}

inline constexpr uint32_t get_min2pow(uint32_t value, uint32_t work = 1) {
  return ((value <= work) ? (work) : (get_min2pow(value, work * 2)));
}

namespace BIT {
// [1, n]
std::array<int, 40000 * 2 + 1> bit;
int32_t n; // nは2の累乗
int sum(int i) {
  int s = 0;
  while (i > 0) {
    s += bit[i];
    i -= i & -i;
  }
  return s;
}
void add(int i, int x) {
  while (i <= n) {
    bit[i] += x;
    i += i & -i;
  }
}
void init() {
  n = 1;
  while (n < N) {
    n *= 2;
  }
  for (int32_t i = 0; i <= n; i++) {
    bit[i] = 0;
  }
}
} // namespace BIT

int main() {
  using std::endl;
  in.sync_with_stdio(false);
  out.sync_with_stdio(false);
  in.tie(nullptr);
  out.tie(nullptr);

  in >> N;
  for (int32_t i = 0; i < N; i++) {
    in >> A[i] >> B[i] >> C[i];
  }

  // Xを求める！！！
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[i] = i;
  }
  func_xtoy(-1000000000.0, zero_V);
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[-zero_V[i].second] = i;
  }
  double X_RES = binary_search_D(-1000000000.0, +1000000000.0, [](double X) {
    func_xtoy(X, tmp_V);
    BIT::init();
    // 交差回数を求める
    int32_t conf = 0;
    int32_t min_ = 0;
    BIT::add((-tmp_V[0].second) + 1, 1);
    for (int32_t i = 1; i < N; i++) {
      conf += BIT::sum(N) - BIT::sum(-tmp_V[i].second);
      BIT::add((-tmp_V[i].second) + 1, 1);
    }
    return conf * 2 < (N * (N - 1) / 2);
  });

  // Yを求める！！！
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[i] = i;
  }
  func_ytox(-1000000000.0, zero_V);
  for (int32_t i = 0; i < N; i++) {
    zero_V_pos[-zero_V[i].second] = i;
  }
  double Y_RES = binary_search_D(-1000000000.0, +1000000000.0, [](double Y) {
    func_ytox(Y, tmp_V);
    BIT::init();
    // 交差回数を求める
    int32_t conf = 0;
    int32_t min_ = 0;
    BIT::add((-tmp_V[0].second) + 1, 1);
    for (int32_t i = 1; i < N; i++) {
      conf += BIT::sum(N) - BIT::sum(-tmp_V[i].second);
      BIT::add((-tmp_V[i].second) + 1, 1);
    }
    return conf * 2 < (N * (N - 1) / 2);
  });

  out << std::fixed << std::setprecision(19) << X_RES << ' ' << Y_RES << endl;

  return 0;
}
#endif