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

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <utility>
using namespace std;

typedef pair<int, int> Pair;

int n;
Pair x[100000];
Pair y[100000];
char xgrp[100000];
char ygrp[100000];

#define BOTH 0
#define A 1
#define B 2
#define C 4
#define D 8

int check(int k) {
  int xmin = x[0].first;
  int xmax = x[n - 1].first;
  int ymin = y[0].first;
  int ymax = y[n - 1].first;
  char a = 0;
  char b = 0;

  memset(xgrp, BOTH, sizeof(xgrp));
  for (int i = 0; i < n; i++) {
    if (abs(x[i].first - xmin) > k && abs(xmax - x[i].first) > k)
      return 0;
    if (abs(x[i].first - xmin) > k)
      xgrp[x[i].second] = A;
    if (abs(xmax - x[i].first) > k)
      xgrp[x[i].second] = B;
  }

  memset(ygrp, BOTH, sizeof(ygrp));
  for (int i = 0; i < n; i++) {
    if (abs(y[i].first - ymin) > k && abs(ymax - y[i].first) > k)
      return 0;
    if (abs(y[i].first - ymin) > k)
      ygrp[y[i].second] = C;
    if (abs(ymax - y[i].first) > k)
      ygrp[y[i].second] = D;
  }

  for (int i = 0; i < n; i++) {
    if (xgrp[i] != BOTH && ygrp[i] != BOTH) {
      if (a == 0) {
        a = xgrp[i] | ygrp[i];
        b = 15 & ~a;
      } else if ((xgrp[i] | ygrp[i]) != a && (xgrp[i] | ygrp[i]) != b)
        return 0;
    }
  }

  return 1;
}

int main() {
  int low;
  int high;

  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    int xi, yi;

    scanf("%d %d", &xi, &yi);
    x[i] = Pair(xi - yi, i);
    y[i] = Pair(xi + yi, i);
  }
  sort(x, x + n);
  sort(y, y + n);

  low = -1;
  high = 400001;
  while (high - low > 1) {
    int mid = (low + high) / 2;
    if (check(mid))
      high = mid;
    else
      low = mid;
  }

  printf("%d\\n", high);
}

Error: 0

Fixed submission:

/*
 *  priority_queueは偉大という"気付き"
 */

#include <algorithm>
#include <cstdio>
#include <set>

using namespace std;

typedef pair<int, int> P;

// set A, B
#define UNDEF 0
#define A 1
#define B 2

// rotate 45°
#define X 0
#define Y 1

int ans;
int n;
multiset<P> sets[3][2];
P ps[10000];
bool used[10000];
int type[2] = {A, B};
int coor[2] = {X, Y};

int main() {
  scanf("%d", &n);

  for (int i = 0; i < n; i++) {
    int x, y;

    scanf("%d %d", &x, &y);
    ps[i] = P(x, y);
    sets[UNDEF][X].insert(P(x + y, i));
    sets[UNDEF][Y].insert(P(x - y, i));
  }

  while (sets[UNDEF][X].size() || sets[UNDEF][Y].size()) {
    int peak = -1;
    int peak_i;
    int peak_l;
    int peak_r;

    for (int i = 0; i < 3; i++) {
      int type[2] = {UNDEF, i};
      int coor[2] = {X, Y};

      for (int j = 0; j < 2; j++) {
        for (int k = 0; k < 2; k++) {
          multiset<P>::reverse_iterator minuend;
          multiset<P>::iterator subtrahend;

          while (1) {
            minuend = sets[type[j]][coor[k]].rbegin();
            if (minuend == sets[type[j]][coor[k]].rend())
              break;
            if (type[j] != UNDEF || !used[minuend->second])
              break;
            sets[type[j]][coor[k]].erase(--minuend.base());
          }
          if (minuend == sets[type[j]][coor[k]].rend())
            continue;

          while (1) {
            subtrahend = sets[type[1 - j]][coor[k]].begin();
            if (subtrahend == sets[type[1 - j]][coor[k]].end())
              break;
            if (type[1 - j] != UNDEF || !used[subtrahend->second])
              break;
            sets[type[1 - j]][coor[k]].erase(subtrahend);
          }
          if (subtrahend == sets[type[1 - j]][coor[k]].end())
            continue;

          if (minuend->first - subtrahend->first >= peak) {
            peak = minuend->first - subtrahend->first;
            peak_i = i;
            peak_l = minuend->second;
            peak_r = subtrahend->second;
          }
        }
      }
    }

    if (peak == -1)
      break;

    if (peak_i == UNDEF) {
      int coor[2] = {X, Y};
      int case1 = 0;
      int case2 = 0;
      int tmp;
      P l = ps[peak_l];
      P r = ps[peak_r];
      int l_x = l.first + l.second;
      int l_y = l.first - l.second;
      int r_x = r.first + r.second;
      int r_y = r.first - r.second;

      // つらい
      if (sets[A][X].size() > 0) {
        tmp = l_x - sets[A][X].begin()->first;
        case1 = max(case1, tmp);
        tmp = sets[A][X].rbegin()->first - l_x;
        case1 = max(case1, tmp);
        tmp = l_y - sets[A][Y].begin()->first;
        case1 = max(case1, tmp);
        tmp = sets[A][Y].rbegin()->first - l_y;
        case1 = max(case1, tmp);

        tmp = r_x - sets[A][X].begin()->first;
        case2 = max(case2, tmp);
        tmp = sets[A][X].rbegin()->first - r_x;
        case2 = max(case2, tmp);
        tmp = r_y - sets[A][Y].begin()->first;
        case2 = max(case2, tmp);
        tmp = sets[A][Y].rbegin()->first - r_y;
        case2 = max(case2, tmp);
      }

      if (sets[B][X].size() > 0) {
        tmp = r_x - sets[B][X].begin()->first;
        case1 = max(case1, tmp);
        tmp = sets[B][X].rbegin()->first - r_x;
        case1 = max(case1, tmp);
        tmp = r_y - sets[B][Y].begin()->first;
        case1 = max(case1, tmp);
        tmp = sets[B][Y].rbegin()->first - r_y;
        case1 = max(case1, tmp);

        tmp = l_x - sets[B][X].begin()->first;
        case2 = max(case2, tmp);
        tmp = sets[B][X].rbegin()->first - l_x;
        case2 = max(case2, tmp);
        tmp = l_y - sets[B][Y].begin()->first;
        case2 = max(case2, tmp);
        tmp = sets[B][Y].rbegin()->first - l_y;
        case2 = max(case2, tmp);
      }

      if (case1 < case2) {
        sets[A][X].insert(P(l_x, peak_l));
        sets[A][Y].insert(P(l_y, peak_l));
        sets[B][X].insert(P(r_x, peak_r));
        sets[B][Y].insert(P(r_y, peak_r));
      } else {
        sets[A][X].insert(P(r_x, peak_r));
        sets[A][Y].insert(P(r_y, peak_r));
        sets[B][X].insert(P(l_x, peak_l));
        sets[B][Y].insert(P(l_y, peak_l));
      }

      used[peak_l] = true;
      used[peak_r] = true;
    } else {
      int t = (!used[peak_l]) ? peak_l : peak_r;
      int x = ps[t].first;
      int y = ps[t].second;

      sets[3 - peak_i][X].insert(P(x + y, t));
      sets[3 - peak_i][Y].insert(P(x - y, t));
      used[t] = true;
    }
  }

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      int tmp = sets[type[i]][coor[j]].rbegin()->first -
                sets[type[i]][coor[j]].begin()->first;
      ans = max(ans, tmp);
    }
  }

  printf("%d\\n", ans);
}