Problem p03950 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define printerr(...) fprintf(stderr, __VA_ARGS__)
#define mid ((l + r) >> 1)
const int maxn = 200100;
void chkmax(int &x, int y) { x = x > y ? x : y; }
int Max(int x, int y) { return x > y ? x : y; }
int n, W, H, T;
struct node {
  int x, y;
} a[maxn];
bool cmp(const node &A, const node &B) { return A.y < B.y; }
int b[maxn], c[maxn];
node stk1[maxn], stk2[maxn];
int top1, top2;
int tr[maxn << 2], siz[maxn << 2], tg[maxn << 2];
void Add(int h, int v) {
  if (!siz[h])
    return;
  tg[h] += v;
  tr[h] += v;
}
void push_down(int h) {
  Add(h << 1, tg[h]);
  Add(h << 1 | 1, tg[h]);
  tg[h] = 0;
}
void push_up(int h) {
  tr[h] = Max(tr[h << 1], tr[h << 1 | 1]);
  siz[h] = siz[h << 1] + siz[h << 1 | 1];
}
void Add(int h, int l, int r, int s, int t, int v) {
  if (t < s)
    return;
  if (!siz[h])
    return;
  if (s <= l && r <= t) {
    Add(h, v);
    return;
  }
  push_down(h);
  if (t <= mid)
    Add(h << 1, l, mid, s, t, v);
  else if (s > mid)
    Add(h << 1 | 1, mid + 1, r, s, t, v);
  else {
    Add(h << 1, l, mid, s, mid, v);
    Add(h << 1 | 1, mid + 1, r, mid + 1, t, v);
  }
  push_up(h);
}
void Insert(int h, int l, int r, int p, int v) {
  if (l == r) {
    chkmax(tr[h], v), siz[h]++;
    return;
  }
  push_down(h);
  if (p <= mid)
    Insert(h << 1, l, mid, p, v);
  else
    Insert(h << 1 | 1, mid + 1, r, p, v);
  push_up(h);
}
void Delete(int h, int l, int r, int p) {
  if (l == r) {
    tr[h] = 0, siz[h] = 0;
    return;
  }
  push_down(h);
  if (p <= mid)
    Delete(h << 1, l, mid, p);
  else
    Delete(h << 1 | 1, mid + 1, r, p);
  push_up(h);
}
void Insertl(int x, int y) {
  while (top1 > 0 && stk1[top1].x <= x) {
    Add(1, 1, n, stk1[top1 - 1].y, stk1[top1].y - 1, b[stk1[top1].x]);
    Delete(1, 1, n, stk1[top1].y);
    top1--;
  }
  stk1[++top1] = (node){x, y};
  Add(1, 1, n, stk1[top1 - 1].y, stk1[top1].y - 1, -b[stk1[top1].x]);
  int v;
  if (y >= stk2[top2].y)
    v = W;
  else if (top2 && y < stk2[1].y)
    v = b[stk2[1].x];
  else {
    int l = 1, r = top2;
    while (r - l > 1) {
      if (y >= stk2[mid].y)
        l = mid;
      else
        r = mid;
    }
    v = b[stk2[r].x];
  }
  Insert(1, 1, n, y, v - c[y]);
}
void Insertr(int x, int y) {
  while (top2 > 0 && stk2[top2].x >= x) {
    Add(1, 1, n, stk2[top2 - 1].y, stk2[top2].y - 1, W - b[stk2[top2].x]);
    Delete(1, 1, n, stk2[top2].y);
    top2--;
  }
  stk2[++top2] = (node){x, y};
  Add(1, 1, n, stk2[top2 - 1].y, stk2[top2].y - 1, b[stk2[top2].x] - W);
  int v;
  if (y >= stk1[top1].y)
    v = 0;
  else if (top1 && y < stk1[1].y)
    v = b[stk1[1].x];
  else {
    int l = 1, r = top1;
    while (r - l > 1) {
      if (y >= stk1[mid].y)
        l = mid;
      else
        r = mid;
    }
    v = b[stk1[r].x];
  }
  Insert(1, 1, n, y, W - b[v] - c[y]);
}
int ans;
void solve() {
  memset(tr, 0, sizeof(tr));
  memset(siz, 0, sizeof(siz));
  memset(tg, 0, sizeof(tg));
  sort(a + 1, a + n + 1, cmp);
  top1 = 0, top2 = 0;
  for (T = 1; T <= n; T++) {
    if (T == 1 || a[T].y != a[T - 1].y)
      chkmax(ans, c[a[T].y] + tr[1]);
    if (b[a[T].x] <= W / 2)
      Insertl(a[T].x, a[T].y);
    else
      Insertr(a[T].x, a[T].y);
  }
}
int main() {
  //	freopen("paint.in","r",stdin);
  //	freopen("paint.out","w",stdout);
  scanf("%d%d%d", &W, &H, &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &a[i].x, &a[i].y);
    b[i] = a[i].x, c[i] = a[i].y;
  }
  a[++n] = (node){W / 2, 0};
  b[n] = a[n].x, c[n] = a[n].y;
  a[++n] = (node){W / 2, H};
  b[n] = a[n].x, c[n] = a[n].y;
  a[++n] = (node){0, H / 2};
  b[n] = a[n].x, c[n] = a[n].y;
  a[++n] = (node){W, H / 2};
  b[n] = a[n].x, c[n] = a[n].y;

  sort(b + 1, b + n + 1);
  for (int i = 1; i <= n; i++)
    a[i].x = lower_bound(b + 1, b + n + 1, a[i].x) - b;
  sort(c + 1, c + n + 1);
  for (int i = 1; i <= n; i++)
    a[i].y = lower_bound(c + 1, c + n + 1, a[i].y) - c;

  solve();
  for (int i = 1; i <= n; i++) {
    swap(a[i].x, a[i].y);
    swap(b[i], c[i]);
  }
  swap(W, H);
  solve();

  printf("%d\n", ans * 2);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define printerr(...) fprintf(stderr, __VA_ARGS__)
#define mid ((l + r) >> 1)
const int maxn = 300100;
void chkmax(int &x, int y) { x = x > y ? x : y; }
int Max(int x, int y) { return x > y ? x : y; }
int n, W, H, T;
struct node {
  int x, y;
} a[maxn];
bool cmp(const node &A, const node &B) { return A.y < B.y; }
int b[maxn], c[maxn];
node stk1[maxn], stk2[maxn];
int top1, top2;
int tr[maxn << 2], siz[maxn << 2], tg[maxn << 2];
void Add(int h, int v) {
  if (!siz[h])
    return;
  tg[h] += v;
  tr[h] += v;
}
void push_down(int h) {
  Add(h << 1, tg[h]);
  Add(h << 1 | 1, tg[h]);
  tg[h] = 0;
}
void push_up(int h) {
  tr[h] = Max(tr[h << 1], tr[h << 1 | 1]);
  siz[h] = siz[h << 1] + siz[h << 1 | 1];
}
void Add(int h, int l, int r, int s, int t, int v) {
  if (t < s)
    return;
  if (!siz[h])
    return;
  if (s <= l && r <= t) {
    Add(h, v);
    return;
  }
  push_down(h);
  if (t <= mid)
    Add(h << 1, l, mid, s, t, v);
  else if (s > mid)
    Add(h << 1 | 1, mid + 1, r, s, t, v);
  else {
    Add(h << 1, l, mid, s, mid, v);
    Add(h << 1 | 1, mid + 1, r, mid + 1, t, v);
  }
  push_up(h);
}
void Insert(int h, int l, int r, int p, int v) {
  if (l == r) {
    chkmax(tr[h], v), siz[h]++;
    return;
  }
  push_down(h);
  if (p <= mid)
    Insert(h << 1, l, mid, p, v);
  else
    Insert(h << 1 | 1, mid + 1, r, p, v);
  push_up(h);
}
void Delete(int h, int l, int r, int p) {
  if (l == r) {
    tr[h] = 0, siz[h] = 0;
    return;
  }
  push_down(h);
  if (p <= mid)
    Delete(h << 1, l, mid, p);
  else
    Delete(h << 1 | 1, mid + 1, r, p);
  push_up(h);
}
void Insertl(int x, int y) {
  while (top1 > 0 && stk1[top1].x <= x) {
    Add(1, 1, n, stk1[top1 - 1].y, stk1[top1].y - 1, b[stk1[top1].x]);
    Delete(1, 1, n, stk1[top1].y);
    top1--;
  }
  stk1[++top1] = (node){x, y};
  Add(1, 1, n, stk1[top1 - 1].y, stk1[top1].y - 1, -b[stk1[top1].x]);
  int v;
  if (y >= stk2[top2].y)
    v = W;
  else if (top2 && y < stk2[1].y)
    v = b[stk2[1].x];
  else {
    int l = 1, r = top2;
    while (r - l > 1) {
      if (y >= stk2[mid].y)
        l = mid;
      else
        r = mid;
    }
    v = b[stk2[r].x];
  }
  Insert(1, 1, n, y, v - c[y]);
}
void Insertr(int x, int y) {
  while (top2 > 0 && stk2[top2].x >= x) {
    Add(1, 1, n, stk2[top2 - 1].y, stk2[top2].y - 1, W - b[stk2[top2].x]);
    Delete(1, 1, n, stk2[top2].y);
    top2--;
  }
  stk2[++top2] = (node){x, y};
  Add(1, 1, n, stk2[top2 - 1].y, stk2[top2].y - 1, b[stk2[top2].x] - W);
  int v;
  if (y >= stk1[top1].y)
    v = 0;
  else if (top1 && y < stk1[1].y)
    v = b[stk1[1].x];
  else {
    int l = 1, r = top1;
    while (r - l > 1) {
      if (y >= stk1[mid].y)
        l = mid;
      else
        r = mid;
    }
    v = b[stk1[r].x];
  }
  Insert(1, 1, n, y, W - b[v] - c[y]);
}
int ans;
void solve() {
  memset(tr, 0, sizeof(tr));
  memset(siz, 0, sizeof(siz));
  memset(tg, 0, sizeof(tg));
  sort(a + 1, a + n + 1, cmp);
  top1 = 0, top2 = 0;
  for (T = 1; T <= n; T++) {
    if (T == 1 || a[T].y != a[T - 1].y)
      chkmax(ans, c[a[T].y] + tr[1]);
    if (b[a[T].x] <= W / 2)
      Insertl(a[T].x, a[T].y);
    else
      Insertr(a[T].x, a[T].y);
  }
}
int main() {
  //	freopen("paint.in","r",stdin);
  //	freopen("paint.out","w",stdout);
  scanf("%d%d%d", &W, &H, &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &a[i].x, &a[i].y);
    b[i] = a[i].x, c[i] = a[i].y;
  }
  a[++n] = (node){W / 2, 0};
  b[n] = a[n].x, c[n] = a[n].y;
  a[++n] = (node){W / 2, H};
  b[n] = a[n].x, c[n] = a[n].y;
  a[++n] = (node){0, H / 2};
  b[n] = a[n].x, c[n] = a[n].y;
  a[++n] = (node){W, H / 2};
  b[n] = a[n].x, c[n] = a[n].y;

  sort(b + 1, b + n + 1);
  for (int i = 1; i <= n; i++)
    a[i].x = lower_bound(b + 1, b + n + 1, a[i].x) - b;
  sort(c + 1, c + n + 1);
  for (int i = 1; i <= n; i++)
    a[i].y = lower_bound(c + 1, c + n + 1, a[i].y) - c;

  solve();
  for (int i = 1; i <= n; i++) {
    swap(a[i].x, a[i].y);
    swap(b[i], c[i]);
  }
  swap(W, H);
  solve();

  printf("%d\n", ans * 2);
  return 0;
}