Problem p03950 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define lc (x << 1)
#define rc (x << 1 | 1)
#define F0 q[top[0]][0]
#define F1 q[top[1]][1]
using namespace std;

template <class T> inline void read(T &x) {
  int f = 1;
  x = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  x *= f;
}

/*============ Header Template ============*/

const int N = 100000 + 5;

int W, H, n;
int mx[N << 2], tag[N << 2];
int top[2];

struct node {
  int x, y, w;
} p[N], q[N][2];
int cmp(const node &a, const node &b) { return a.x < b.x; }

void upd(int x) { mx[x] = max(mx[lc], mx[rc]); }

void build(int x, int l, int r) {
  mx[x] = tag[x] = 0;
  if (l == r)
    return;
  int m = (l + r) >> 1;
  build(lc, l, m);
  build(rc, m + 1, r);
}

void make_tag(int x, int val) {
  mx[x] += val;
  tag[x] += val;
}

void push_down(int x) {
  if (tag[x]) {
    make_tag(lc, tag[x]);
    make_tag(rc, tag[x]);
    tag[x] = 0;
  }
}

void modify(int x, int l, int r, int s, int t, int val) {
  if (s > t)
    return;
  // if (x == 1) printf("BOO %d %d %d\n", s, t, val);
  if (s <= l && r <= t) {
    make_tag(x, val);
    return;
  }
  push_down(x);
  int m = (l + r) >> 1;
  if (s <= m)
    modify(lc, l, m, s, t, val);
  if (m < t)
    modify(rc, m + 1, r, s, t, val);
  upd(x);
}

int getmax(int x, int l, int r, int s, int t) {
  if (s <= l && r <= t)
    return mx[x];
  push_down(x);
  int m = (l + r) >> 1, ans = 0;
  if (s <= m)
    ans = max(ans, getmax(lc, l, m, s, t));
  if (m < t)
    ans = max(ans, getmax(rc, m + 1, r, s, t));
  return ans;
}

int solve() {
  sort(p + 1, p + n + 1, cmp);
  top[0] = top[1] = 0;
  int ans = max(W, H), num = n;
  if (p[n].x != W)
    p[++num] = (node){W, H};
  // printf("num = %d\n", num);
  // for (int i = 1; i <= num; i++) printf("%d %d\n", p[i].x, p[i].y);
  build(1, 1, num);
  for (int i = num; i; i--) {
    if (i < num) {
      // printf("x = %d ans = %d\n", i, getmax(1, 1, num, i + 1, num) - p[i].x);
      ans = max(ans, getmax(1, 1, num, i + 1, num) - p[i].x);
    }
    if (p[i].y <= H / 2) { // 1
      while (top[1] && F1.w < p[i].y) {
        modify(1, 1, num, F1.x, F1.y, F1.w);
        top[1]--;
      }
      q[top[1] + 1][1] = (node){i + 1, top[1] ? F1.x - 1 : num, p[i].y};
      top[1]++;
      modify(1, 1, num, F1.x, F1.y, -F1.w);
    } else { // 0
      while (top[0] && F0.w > p[i].y) {
        modify(1, 1, num, F0.x, F0.y, -F0.w);
        top[0]--;
      }
      q[top[0] + 1][0] = (node){i + 1, top[0] ? F0.x - 1 : num, p[i].y};
      top[0]++;
      modify(1, 1, num, F0.x, F0.y, F0.w);
    }
    q[++top[1]][1] = (node){i, i, 0};
    q[++top[0]][0] = (node){i, i, H};
    modify(1, 1, num, i, i, p[i].x + H);
  }
  if (p[1].x)
    ans = max(ans, getmax(1, 1, num, 1, num));
  return ans;
}

int main() {
  read(W), read(H), read(n);
  for (int i = 1; i <= n; i++)
    read(p[i].x), read(p[i].y);
  int ans = solve();
  for (int i = 1; i <= n; i++)
    swap(p[i].x, p[i].y);
  swap(W, H);
  ans = max(ans, solve());
  // ans = solve();
  printf("%d\n", ans * 2);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define lc (x << 1)
#define rc (x << 1 | 1)
#define F0 q[top[0]][0]
#define F1 q[top[1]][1]
using namespace std;

template <class T> inline void read(T &x) {
  int f = 1;
  x = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  x *= f;
}

/*============ Header Template ============*/

const int N = 300000 + 5;

int W, H, n;
int mx[N << 2], tag[N << 2];
int top[2];

struct node {
  int x, y, w;
} p[N], q[N][2];
int cmp(const node &a, const node &b) { return a.x < b.x; }

void upd(int x) { mx[x] = max(mx[lc], mx[rc]); }

void build(int x, int l, int r) {
  mx[x] = tag[x] = 0;
  if (l == r)
    return;
  int m = (l + r) >> 1;
  build(lc, l, m);
  build(rc, m + 1, r);
}

void make_tag(int x, int val) {
  mx[x] += val;
  tag[x] += val;
}

void push_down(int x) {
  if (tag[x]) {
    make_tag(lc, tag[x]);
    make_tag(rc, tag[x]);
    tag[x] = 0;
  }
}

void modify(int x, int l, int r, int s, int t, int val) {
  if (s > t)
    return;
  // if (x == 1) printf("BOO %d %d %d\n", s, t, val);
  if (s <= l && r <= t) {
    make_tag(x, val);
    return;
  }
  push_down(x);
  int m = (l + r) >> 1;
  if (s <= m)
    modify(lc, l, m, s, t, val);
  if (m < t)
    modify(rc, m + 1, r, s, t, val);
  upd(x);
}

int getmax(int x, int l, int r, int s, int t) {
  if (s <= l && r <= t)
    return mx[x];
  push_down(x);
  int m = (l + r) >> 1, ans = 0;
  if (s <= m)
    ans = max(ans, getmax(lc, l, m, s, t));
  if (m < t)
    ans = max(ans, getmax(rc, m + 1, r, s, t));
  return ans;
}

int solve() {
  sort(p + 1, p + n + 1, cmp);
  top[0] = top[1] = 0;
  int ans = max(W, H), num = n;
  if (p[n].x != W)
    p[++num] = (node){W, H};
  // printf("num = %d\n", num);
  // for (int i = 1; i <= num; i++) printf("%d %d\n", p[i].x, p[i].y);
  build(1, 1, num);
  for (int i = num; i; i--) {
    if (i < num) {
      // printf("x = %d ans = %d\n", i, getmax(1, 1, num, i + 1, num) - p[i].x);
      ans = max(ans, getmax(1, 1, num, i + 1, num) - p[i].x);
    }
    if (p[i].y <= H / 2) { // 1
      while (top[1] && F1.w < p[i].y) {
        modify(1, 1, num, F1.x, F1.y, F1.w);
        top[1]--;
      }
      q[top[1] + 1][1] = (node){i + 1, top[1] ? F1.x - 1 : num, p[i].y};
      top[1]++;
      modify(1, 1, num, F1.x, F1.y, -F1.w);
    } else { // 0
      while (top[0] && F0.w > p[i].y) {
        modify(1, 1, num, F0.x, F0.y, -F0.w);
        top[0]--;
      }
      q[top[0] + 1][0] = (node){i + 1, top[0] ? F0.x - 1 : num, p[i].y};
      top[0]++;
      modify(1, 1, num, F0.x, F0.y, F0.w);
    }
    q[++top[1]][1] = (node){i, i, 0};
    q[++top[0]][0] = (node){i, i, H};
    modify(1, 1, num, i, i, p[i].x + H);
  }
  if (p[1].x)
    ans = max(ans, getmax(1, 1, num, 1, num));
  return ans;
}

int main() {
  read(W), read(H), read(n);
  for (int i = 1; i <= n; i++)
    read(p[i].x), read(p[i].y);
  int ans = solve();
  for (int i = 1; i <= n; i++)
    swap(p[i].x, p[i].y);
  swap(W, H);
  ans = max(ans, solve());
  // ans = solve();
  printf("%d\n", ans * 2);
  return 0;
}