Problem p03685 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
int x[100005][2], y[100005][2];
int left[100005], right[100005];
int f[2][400005][19];
int pow2[25], log2[400005];
int map[200005];

int isGood(int x, int y, int r, int c) {
  if (x == 0 || x == r)
    return 1;
  if (y == 0 || y == c)
    return 1;
  return 0;
}

int getId(int x, int y, int r, int c) {
  if (x == 0)
    return y + 1;
  else if (y == c)
    return c + 1 + x;
  else if (x == r)
    return c + 1 + r + c - y;
  else
    return 2 * c + 1 + r + r - x;
}

int isInside(int x, int l, int r) {
  if (x < l)
    return 0;
  if (x > r)
    return 0;
  return 1;
}

int max(int a, int b) { return a > b ? a : b; }

int min(int a, int b) { return a > b ? b : a; }

// f[0][i]: right at i min left, f[1][i]: left at i max right
void buildTable(int size, int n) {
  int inf = 1e8 + 7;
  for (int i = 1; i <= n; i++) {
    f[0][i][0] = inf;
    f[1][i][0] = -inf;
  }
  for (int i = 1; i <= size; i++) {
    int l = left[i], r = right[i];
    f[0][r][0] = min(f[0][r][0], l);
    f[1][l][0] = max(f[1][l][0], r);
  }
  log2[0] = 0;
  int base = 1;
  for (int i = 1; i <= n; i++) {
    log2[i] = log2[i - 1];
    if (base * 2 <= i)
      base *= 2, log2[i]++;
  }
  pow2[0] = 1;
  for (int j = 1; j <= 18; j++) {
    pow2[j] = pow2[j - 1] * 2;
    for (int i = 1; i <= n; i++) {
      if (i + pow2[j] - 1 > n)
        f[0][i][j] = inf, f[1][i][j] = -inf;
      else {
        f[0][i][j] = min(f[0][i][j - 1], f[0][i + pow2[j - 1]][j - 1]);
        f[1][i][j] = max(f[1][i][j - 1], f[1][i + pow2[j - 1]][j - 1]);
      }
    }
  }
}

int spMin(int l, int r) {
  int k = log2[r - l + 1];
  return min(f[0][l][k], f[0][r - pow2[k] + 1][k]);
}

int spMax(int l, int r) {
  int k = log2[r - l + 1];
  return max(f[1][l][k], f[1][r - pow2[k] + 1][k]);
}

int getId(int u, int n) {
  int L = 1, R = n;
  int res = -1;
  while (L <= R) {
    int M = (L + R) / 2;
    if (map[M] <= u) {
      res = M;
      L = M + 1;
    } else
      R = M - 1;
  }
  return res;
}

void mapping(int n) {
  int size = 0;
  for (int i = 1; i <= n; i++) {
    map[++size] = left[i];
    map[++size] = right[i];
  }
  std::sort(map + 1, map + 1 + size);
  for (int i = 1; i <= n; i++) {
    left[i] = getId(left[i], size);
    right[i] = getId(right[i], size);
  }
}

int main() {
  int r, c, n;
  scanf("%d%d%d", &r, &c, &n);
  int size = 0;
  for (int i = 1; i <= n; i++) {
    int x0, y0, x1, y1;
    scanf("%d%d%d%d", &x0, &y0, &x1, &y1);
    if (isGood(x0, y0, r, c) && isGood(x1, y1, r, c)) {
      size++;
      x[size][0] = x0, x[size][1] = x1;
      y[size][0] = y0, y[size][1] = y1;
    }
  }
  for (int i = 1; i <= size; i++) {
    left[i] = getId(x[i][0], y[i][0], r, c);
    right[i] = getId(x[i][1], y[i][1], r, c);
    if (left[i] > right[i]) {
      int t = left[i];
      left[i] = right[i];
      right[i] = t;
    }
    // printf("left[%d] = %d, right[%d] = %d\n",i,left[i],i,right[i]);
  }
  mapping(size);
  buildTable(size, 2 * c + 2 * r + 1);
  int ok = 1;
  for (int i = 1; i <= size; i++) {
    int l = left[i], r = right[i];
    if (r - l >= 2) {
      int minn = spMin(l + 1, r - 1), maxn = spMax(l + 1, r - 1);
      if (minn < l || maxn > r)
        ok = 0;
    }
  }
  if (ok)
    printf("YES\n");
  else
    printf("NO\n");
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
int x[100005][2], y[100005][2];
int left[100005], right[100005];
int f[2][400005][19];
int pow2[25], log2[400005];
int map[200005];

int isGood(int x, int y, int r, int c) {
  if (x == 0 || x == r)
    return 1;
  if (y == 0 || y == c)
    return 1;
  return 0;
}

int getId(int x, int y, int r, int c) {
  if (x == 0)
    return y + 1;
  else if (y == c)
    return c + 1 + x;
  else if (x == r)
    return c + 1 + r + c - y;
  else
    return 2 * c + 1 + r + r - x;
}

int isInside(int x, int l, int r) {
  if (x < l)
    return 0;
  if (x > r)
    return 0;
  return 1;
}

int max(int a, int b) { return a > b ? a : b; }

int min(int a, int b) { return a > b ? b : a; }

// f[0][i]: right at i min left, f[1][i]: left at i max right
void buildTable(int size, int n) {
  int inf = 1e8 + 7;
  for (int i = 1; i <= n; i++) {
    f[0][i][0] = inf;
    f[1][i][0] = -inf;
  }
  for (int i = 1; i <= size; i++) {
    int l = left[i], r = right[i];
    f[0][r][0] = min(f[0][r][0], l);
    f[1][l][0] = max(f[1][l][0], r);
  }
  log2[0] = 0;
  int base = 1;
  for (int i = 1; i <= n; i++) {
    log2[i] = log2[i - 1];
    if (base * 2 <= i)
      base *= 2, log2[i]++;
  }
  pow2[0] = 1;
  for (int j = 1; j <= 18; j++) {
    pow2[j] = pow2[j - 1] * 2;
    for (int i = 1; i <= n; i++) {
      if (i + pow2[j] - 1 > n)
        f[0][i][j] = inf, f[1][i][j] = -inf;
      else {
        f[0][i][j] = min(f[0][i][j - 1], f[0][i + pow2[j - 1]][j - 1]);
        f[1][i][j] = max(f[1][i][j - 1], f[1][i + pow2[j - 1]][j - 1]);
      }
    }
  }
}

int spMin(int l, int r) {
  int k = log2[r - l + 1];
  return min(f[0][l][k], f[0][r - pow2[k] + 1][k]);
}

int spMax(int l, int r) {
  int k = log2[r - l + 1];
  return max(f[1][l][k], f[1][r - pow2[k] + 1][k]);
}

int getId(int u, int n) {
  int L = 1, R = n;
  int res = -1;
  while (L <= R) {
    int M = (L + R) / 2;
    if (map[M] <= u) {
      res = M;
      L = M + 1;
    } else
      R = M - 1;
  }
  return res;
}

void mapping(int n) {
  int size = 0;
  for (int i = 1; i <= n; i++) {
    map[++size] = left[i];
    map[++size] = right[i];
  }
  std::sort(map + 1, map + 1 + size);
  for (int i = 1; i <= n; i++) {
    left[i] = getId(left[i], size);
    right[i] = getId(right[i], size);
  }
}

int main() {
  int r, c, n;
  scanf("%d%d%d", &r, &c, &n);
  int size = 0;
  for (int i = 1; i <= n; i++) {
    int x0, y0, x1, y1;
    scanf("%d%d%d%d", &x0, &y0, &x1, &y1);
    if (isGood(x0, y0, r, c) && isGood(x1, y1, r, c)) {
      size++;
      x[size][0] = x0, x[size][1] = x1;
      y[size][0] = y0, y[size][1] = y1;
    }
  }
  for (int i = 1; i <= size; i++) {
    left[i] = getId(x[i][0], y[i][0], r, c);
    right[i] = getId(x[i][1], y[i][1], r, c);
    if (left[i] > right[i]) {
      int t = left[i];
      left[i] = right[i];
      right[i] = t;
    }
    // printf("left[%d] = %d, right[%d] = %d\n",i,left[i],i,right[i]);
  }
  mapping(size);
  buildTable(size, 2 * size);
  int ok = 1;
  for (int i = 1; i <= size; i++) {
    int l = left[i], r = right[i];
    if (r - l >= 2) {
      int minn = spMin(l + 1, r - 1), maxn = spMax(l + 1, r - 1);
      if (minn < l || maxn > r)
        ok = 0;
    }
  }
  if (ok)
    printf("YES\n");
  else
    printf("NO\n");
  return 0;
}