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

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

struct Point {
  double x, y;
};
struct Square {
  double left, right, top, bottom;
};

bool include(const Square &s, const Point &p) {
  return s.left <= p.x && p.x <= s.right && s.bottom <= p.y && p.y <= s.top;
}

bool ok(const vector<Point> &point, double d) {
  Square A = {point.front().x, point.front().x + d, 0, 0};
  Square B = {point.back().x - d, point.back().x, 0, 0};
  double lowA = 1e9, highA = -1e9;
  double lowB = 1e9, highB = -1e9;
  for (const auto &p : point) {
    if (p.x <= A.right) {
      lowA = std::min(lowA, p.y);
      highA = std::max(highA, p.y);
    }
    if (B.left <= p.x) {
      lowB = std::min(lowB, p.y);
      highB = std::max(highB, p.y);
    }
  }
  A.top = highA;
  A.bottom = highA - d;
  B.top = lowB + d;
  B.bottom = lowB;
  if (all_of(begin(point), end(point),
             [&](const Point &p) { return include(A, p) || include(B, p); }))
    return true;
  A.top = lowA + d;
  A.bottom = lowA;
  B.top = highB;
  B.bottom = highB - d;
  if (all_of(begin(point), end(point),
             [&](const Point &p) { return include(A, p) || include(B, p); }))
    return true;
  return false;
}

int main() {
  int N;
  cin >> N;
  vector<Point> point(N);
  for (auto &p : point)
    cin >> p.x >> p.y;
  for (auto &p : point)
    p = {p.x / sqrt(2) - p.y / sqrt(2), p.x / sqrt(2) + p.y / sqrt(2)};
  sort(begin(point), end(point),
       [](const Point &lhs, const Point &rhs) { return lhs.x < rhs.x; });
  double low = 0, high = 3e5;
  while (1e-3 < high - low) {
    double middle = (low + high) / 2.0;
    ok(point, middle) ? (high = middle) : (low = middle);
  }
  cout << int(high * sqrt(2)) << endl;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <vector>
typedef double Data;
class RangeMinimumQuery {
public:
  static const Data INF;
  RangeMinimumQuery(int s) : size_(1) {
    while (size_ < s)
      size_ <<= 1;
    for (int i = 0; i < (size_ << 1) - 1; ++i)
      node_[i] = INF;
  }
  Data find(int left, int right) const {
    return query(left, right, 0, 0, size_ - 1);
  }
  void update(int index, Data value) {
    int i = index + size_ - 1;
    node_[i] = value;
    while ((i = parent(i)) != NIL)
      node_[i] = std::min(node_[left_child(i)], node_[right_child(i)]);
  }

private:
  int parent(int node) const { return node == 0 ? NIL : (node - 1) >> 1; }
  int left_child(int node) const { return (node << 1) + 1; }
  int right_child(int node) const { return (node << 1) + 2; }
  Data query(int a, int b, int k, int l, int r) const {
    if (b < l || r < a)
      return INF;
    if (a <= l && r <= b)
      return node_[k];
    Data vl = query(a, b, left_child(k), l, (l + r) / 2);
    Data vr = query(a, b, right_child(k), (l + r) / 2 + 1, r);
    return std::min(vl, vr);
  }
  static const int NIL;
  int size_;
  Data node_[200002];
};
const Data RangeMinimumQuery::INF = 1e9;
const int RangeMinimumQuery::NIL = -1;

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

const double PI = acos(-1.0);

struct Point {
  double x, y;
};
struct Square {
  double left, right, top, bottom;
};

bool include(const Square &s, const Point &p) {
  return s.left <= p.x && p.x <= s.right && s.bottom <= p.y && p.y <= s.top;
}

bool ok(const vector<Point> &point, double d, const RangeMinimumQuery &maxy,
        const RangeMinimumQuery &miny) {
  int leftA = 0;
  int rightA =
      upper_bound(begin(point), end(point), point.front().x + d,
                  [](double lhs, const Point &rhs) { return lhs < rhs.x; }) -
      begin(point) - 1;
  int leftB =
      lower_bound(begin(point), end(point), point.back().x - d,
                  [](const Point &lhs, double val) { return lhs.x < val; }) -
      begin(point);
  int rightB = point.size() - 1;
  if (rightA < leftB) {
    double lowA = miny.find(leftA, rightA), highA = -maxy.find(leftA, rightA);
    double lowB = miny.find(leftB, rightB), highB = -maxy.find(leftB, rightB);
    if (rightA + 1 == leftB)
      if (highA - lowA <= d && highB - lowB <= d)
        return true;
  } else {
    Square A = {point.front().x, point.front().x + d, 0, 0};
    Square B = {point.back().x - d, point.back().x, 0, 0};
    A.top = -maxy.find(leftA, rightA);
    A.bottom = A.top - d;
    B.bottom = miny.find(leftB, rightB);
    B.top = B.bottom + d;
    if (all_of(begin(point), end(point),
               [&](const Point &p) { return include(A, p) || include(B, p); }))
      return true;
    A.bottom = miny.find(leftA, rightA);
    A.top = A.bottom + d;
    B.top = -maxy.find(leftB, rightB);
    B.bottom = B.top - d;
    if (all_of(begin(point), end(point),
               [&](const Point &p) { return include(A, p) || include(B, p); }))
      return true;
  }
  return false;
}

int main() {
  int N;
  cin >> N;
  vector<Point> point(N);
  for (auto &p : point)
    cin >> p.x >> p.y;
  for (auto &p : point)
    p = {p.x * cos(PI / 4.0) - p.y * sin(PI / 4.0),
         p.x * sin(PI / 4.0) + p.y * cos(PI / 4.0)};
  sort(begin(point), end(point),
       [](const Point &lhs, const Point &rhs) { return lhs.x < rhs.x; });
  RangeMinimumQuery maxy(N), miny(N);
  for (int i = 0; i < N; ++i) {
    maxy.update(i, -point[i].y);
    miny.update(i, point[i].y);
  }
  const double EPS = 1e-3;
  double low = -300000.0, high = 300000.0;
  while (EPS < high - low) {
    double middle = (low + high) / 2.0;
    ok(point, middle, maxy, miny) ? (high = middle) : (low = middle);
  }
  cout << int(high * sqrt(2.0)) << endl;
}