Problem p03950 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
struct P {
  int x, y;
  P(int x = 0, int y = 0) : x(x), y(y) {}
  friend bool operator<(P a, P b) { return a.x < b.x; }
} p[300005];
int w, h, n, mx[1200005], lz[1200005], s1[300005], s2[300005], ans, t1, t2;
void down(int x) {
  mx[x * 2] += lz[x];
  mx[x * 2 + 1] += lz[x];
  lz[x * 2] += lz[x];
  lz[x * 2 + 1] += lz[x];
  lz[x] = 0;
}
void upd(int x, int l, int r, int b, int e, int v) {
  down(x);
  if (b <= l && r <= e) {
    lz[x] += v;
    mx[x] += v;
    return;
  }
  int mid = (l + r) >> 1;
  if (b <= mid)
    upd(x * 2, l, mid, b, e, v);
  if (e > mid)
    upd(x * 2 + 1, mid + 1, r, b, e, v);
  mx[x] = max(mx[x * 2], mx[x * 2 + 1]);
}
void gao() {
  sort(p + 1, p + n + 1);
  memset(mx, 0, sizeof(mx));
  memset(lz, 0, sizeof(lz));
  t1 = t2 = 0;
  s1[t1] = s2[t2] = 1;
  upd(1, 1, n, 1, n, h);
  for (int i = 2; i <= n; i++) {
    upd(1, 1, n, 1, i - 1, p[i].x - p[i - 1].x);
    ans = max(ans, mx[1] * 2);
    if (p[i].y >= h / 2) {
      upd(1, 1, n, s1[t1], i - 1, p[i].y - h);
      while (t1 && p[s1[t1]].y >= p[i].y)
        upd(1, 1, n, s1[t1 - 1], s1[t1] - 1, p[i].y - p[s1[t1]].y), t1--;
      s1[++t1] = i;
    } else {
      upd(1, 1, n, s2[t2], i - 1, -p[i].y);
      while (t2 && p[s2[t2]].y <= p[i].y)
        upd(1, 1, n, s2[t2 - 1], s2[t2] - 1, p[s2[t2]].y - p[i].y), t2--;
      s2[++t2] = i;
    }
  }
}
int main() {
  scanf("%d%d%d", &w, &h, &n);
  n++;
  p[1] = P(0, 0);
  n++;
  p[n] = P(w, h);
  ans = 2 * max(w, h) + 2;
  for (int i = 2; i < n; i++)
    scanf("%d%d", &p[i].x, &p[i].y);
  gao();
  for (int i = 1; i <= n; i++)
    swap(p[i].x, p[i].y);
  swap(w, h);
  gao();
  printf("%d\n", ans);
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
struct P {
  int x, y;
  P(int x = 0, int y = 0) : x(x), y(y) {}
  friend bool operator<(P a, P b) { return a.x < b.x; }
} p[1200005];
int w, h, n, mx[2500005], lz[2500005], s1[1200005], s2[1200005], ans, t1, t2;
void down(int x) {
  mx[x * 2] += lz[x];
  mx[x * 2 + 1] += lz[x];
  lz[x * 2] += lz[x];
  lz[x * 2 + 1] += lz[x];
  lz[x] = 0;
}
void upd(int x, int l, int r, int b, int e, int v) {
  down(x);
  if (b <= l && r <= e) {
    lz[x] += v;
    mx[x] += v;
    return;
  }
  int mid = (l + r) >> 1;
  if (b <= mid)
    upd(x * 2, l, mid, b, e, v);
  if (e > mid)
    upd(x * 2 + 1, mid + 1, r, b, e, v);
  mx[x] = max(mx[x * 2], mx[x * 2 + 1]);
}
void gao() {
  sort(p + 1, p + n + 1);
  memset(mx, 0, sizeof(mx));
  memset(lz, 0, sizeof(lz));
  t1 = t2 = 0;
  s1[t1] = s2[t2] = 1;
  upd(1, 1, n, 1, n, h);
  for (int i = 2; i <= n; i++) {
    upd(1, 1, n, 1, i - 1, p[i].x - p[i - 1].x);
    ans = max(ans, mx[1] * 2);
    if (p[i].y >= h / 2) {
      upd(1, 1, n, s1[t1], i - 1, p[i].y - h);
      while (t1 && p[s1[t1]].y >= p[i].y)
        upd(1, 1, n, s1[t1 - 1], s1[t1] - 1, p[i].y - p[s1[t1]].y), t1--;
      s1[++t1] = i;
    } else {
      upd(1, 1, n, s2[t2], i - 1, -p[i].y);
      while (t2 && p[s2[t2]].y <= p[i].y)
        upd(1, 1, n, s2[t2 - 1], s2[t2] - 1, p[s2[t2]].y - p[i].y), t2--;
      s2[++t2] = i;
    }
  }
}
int main() {
  scanf("%d%d%d", &w, &h, &n);
  n++;
  p[1] = P(0, 0);
  n++;
  p[n] = P(w, h);
  ans = 2 * max(w, h) + 2;
  for (int i = 2; i < n; i++)
    scanf("%d%d", &p[i].x, &p[i].y);
  gao();
  for (int i = 1; i <= n; i++)
    swap(p[i].x, p[i].y);
  swap(w, h);
  gao();
  printf("%d\n", ans);
}