Problem p03950 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define debug(...) fprintf(stderr, __VA_ARGS__);
using namespace std;
typedef long long ll;
const int MAXSIZE = 10000020;
int bufpos;
char buf[MAXSIZE];
#define NEG 0
void init() {
  freopen("color.in", "r", stdin);
  freopen("color.out", "w", stdout);
  buf[fread(buf, 1, MAXSIZE, stdin)] = '\0';
  bufpos = 0;
}
#if NEG
int readint() {
  bool isneg;
  int val = 0;
  for (; !isdigit(buf[bufpos]) && buf[bufpos] != '-'; bufpos++)
    ;
  bufpos += (isneg = buf[bufpos] == '-');
  for (; isdigit(buf[bufpos]); bufpos++)
    val = val * 10 + buf[bufpos] - '0';
  return isneg ? -val : val;
}
#else
int readint() {
  int val = 0;
  for (; !isdigit(buf[bufpos]); bufpos++)
    ;
  for (; isdigit(buf[bufpos]); bufpos++)
    val = val * 10 + buf[bufpos] - '0';
  return val;
}
#endif
char readchar() {
  for (; isspace(buf[bufpos]); bufpos++)
    ;
  return buf[bufpos++];
}
int readstr(char *s) {
  int cur = 0;
  for (; isspace(buf[bufpos]); bufpos++)
    ;
  for (; !isspace(buf[bufpos]); bufpos++)
    s[cur++] = buf[bufpos];
  s[cur] = '\0';
  return cur;
}
const int maxn = 310002;
const int INF = 0x3f3f3f3f;
struct segtree {
  int n;
  int t[maxn * 4], ad[maxn * 4];
  void init(int n) {
    this->n = n;
    memset(t, 0, sizeof(t));
    memset(ad, 0, sizeof(ad));
  }
  int ul, ur, uv;
  void update(int o, int l, int r) {
    // debug("o=%d l=%d r=%d ul=%d ur=%d\n",o,l,r,ul,ur);
    if (ul <= l && ur >= r) {
      ad[o] += uv;
      t[o] += uv;
      return;
    }
    int mid = (l + r) / 2;
    if (ul <= mid)
      update(o * 2, l, mid);
    if (ur > mid)
      update(o * 2 + 1, mid + 1, r);
    t[o] = max(t[o * 2], t[o * 2 + 1]) + ad[o];
  }
  void add(int l, int r, int v) {
    if (l > r)
      return;
    // debug("add %d %d %d\n",l,r,v);
    ul = l, ur = r, uv = v;
    update(1, 1, n);
  }
  int ql, qr;
  int query(int o, int l, int r) {
    if (ql <= l && qr >= r)
      return t[o];
    int mid = (l + r) / 2, ans = -INF;
    if (ql <= mid)
      ans = max(ans, query(o * 2, l, mid));
    if (qr > mid)
      ans = max(ans, query(o * 2 + 1, mid + 1, r));
    return ans + ad[o];
  }
  int query(int l, int r) {
    if (l > r)
      return -INF;
    ql = l, qr = r;
    return query(1, 1, n);
  }
} t;
struct point {
  int x, y;
  bool operator<(const point &rhs) const { return y < rhs.y; }
} a[maxn];
int h, w, n;
int s1[maxn], t1, s2[maxn], t2;
int work() {
  sort(a + 1, a + n + 1);
  t.init(n);
  int o = h / 2;
  s1[0] = s2[0] = 1;
  t1 = t2 = 0;
  int ans = 0;
  // debug("n=%d\n",n);
  for (int i = 1; i <= n; i++) {
    ans = max(ans, t.query(1, i - 1) + a[i].y);
    // debug("i=%d\n",i);
    if (a[i].x <= o) {
      while (t1 && a[s1[t1]].x < a[i].x) {
        t.add(s1[t1 - 1], s1[t1] - 1, a[s1[t1]].x);
        t1--;
      }
      t.add(s1[t1], i - 1, -a[i].x);
      s1[++t1] = i;
    } else {
      t.add(s2[t2], i - 1, -h);
      while (t2 && a[s2[t2]].x >= a[i].x) {
        t.add(s2[t2 - 1], s2[t2], -a[s2[t2]].x);
        t2--;
      }
      t.add(s2[t2], i - 1, a[i].x);
      s2[++t2] = i;
    }
    // debug("i=%d\n",i);
    t.add(i, i, h - a[i].y);
  }
  // debug("ans=%d\n",ans);
  return ans;
}
int main() {
  init();
  h = readint(), w = readint(), n = readint();
  for (int i = 1; i <= n; i++)
    a[i].x = readint(), a[i].y = readint();
  a[++n] = (point){0, 0};
  a[++n] = (point){h, w};
  // debug("233\n");
  int ans = work();
  // debug("233\n");
  swap(h, w);
  for (int i = 1; i <= n; i++)
    swap(a[i].x, a[i].y);
  ans = max(ans, work());
  printf("%d", ans * 2);
}

Fixed submission:
#include <bits/stdc++.h>
#define debug(...) fprintf(stderr, __VA_ARGS__);
using namespace std;
typedef long long ll;
const int MAXSIZE = 10000020;
int bufpos;
char buf[MAXSIZE];
#define NEG 0
void init() {
  // freopen("color.in","r",stdin);
  // freopen("color.out","w",stdout);
  buf[fread(buf, 1, MAXSIZE, stdin)] = '\0';
  bufpos = 0;
}
#if NEG
int readint() {
  bool isneg;
  int val = 0;
  for (; !isdigit(buf[bufpos]) && buf[bufpos] != '-'; bufpos++)
    ;
  bufpos += (isneg = buf[bufpos] == '-');
  for (; isdigit(buf[bufpos]); bufpos++)
    val = val * 10 + buf[bufpos] - '0';
  return isneg ? -val : val;
}
#else
int readint() {
  int val = 0;
  for (; !isdigit(buf[bufpos]); bufpos++)
    ;
  for (; isdigit(buf[bufpos]); bufpos++)
    val = val * 10 + buf[bufpos] - '0';
  return val;
}
#endif
char readchar() {
  for (; isspace(buf[bufpos]); bufpos++)
    ;
  return buf[bufpos++];
}
int readstr(char *s) {
  int cur = 0;
  for (; isspace(buf[bufpos]); bufpos++)
    ;
  for (; !isspace(buf[bufpos]); bufpos++)
    s[cur++] = buf[bufpos];
  s[cur] = '\0';
  return cur;
}
const int maxn = 310002;
const int INF = 0x3f3f3f3f;
struct segtree {
  int n;
  int t[maxn * 4], ad[maxn * 4];
  void init(int n) {
    this->n = n;
    memset(t, 0, sizeof(t));
    memset(ad, 0, sizeof(ad));
  }
  int ul, ur, uv;
  void update(int o, int l, int r) {
    // debug("o=%d l=%d r=%d ul=%d ur=%d\n",o,l,r,ul,ur);
    if (ul <= l && ur >= r) {
      ad[o] += uv;
      t[o] += uv;
      return;
    }
    int mid = (l + r) / 2;
    if (ul <= mid)
      update(o * 2, l, mid);
    if (ur > mid)
      update(o * 2 + 1, mid + 1, r);
    t[o] = max(t[o * 2], t[o * 2 + 1]) + ad[o];
  }
  void add(int l, int r, int v) {
    if (l > r)
      return;
    // debug("add %d %d %d\n",l,r,v);
    ul = l, ur = r, uv = v;
    update(1, 1, n);
  }
  int ql, qr;
  int query(int o, int l, int r) {
    if (ql <= l && qr >= r)
      return t[o];
    int mid = (l + r) / 2, ans = -INF;
    if (ql <= mid)
      ans = max(ans, query(o * 2, l, mid));
    if (qr > mid)
      ans = max(ans, query(o * 2 + 1, mid + 1, r));
    return ans + ad[o];
  }
  int query(int l, int r) {
    if (l > r)
      return -INF;
    ql = l, qr = r;
    return query(1, 1, n);
  }
} t;
struct point {
  int x, y;
  bool operator<(const point &rhs) const { return y < rhs.y; }
} a[maxn];
int h, w, n;
int s1[maxn], t1, s2[maxn], t2;
int work() {
  sort(a + 1, a + n + 1);
  t.init(n);
  int o = h / 2;
  s1[0] = s2[0] = 1;
  t1 = t2 = 0;
  int ans = 0;
  // debug("n=%d\n",n);
  for (int i = 1; i <= n; i++) {
    ans = max(ans, t.query(1, i - 1) + a[i].y);
    // debug("i=%d\n",i);
    if (a[i].x <= o) {
      while (t1 && a[s1[t1]].x < a[i].x) {
        t.add(s1[t1 - 1], s1[t1] - 1, a[s1[t1]].x);
        t1--;
      }
      t.add(s1[t1], i - 1, -a[i].x);
      s1[++t1] = i;
    } else {
      t.add(s2[t2], i - 1, -h);
      while (t2 && a[s2[t2]].x >= a[i].x) {
        t.add(s2[t2 - 1], s2[t2], -a[s2[t2]].x);
        t2--;
      }
      t.add(s2[t2], i - 1, a[i].x);
      s2[++t2] = i;
    }
    // debug("i=%d\n",i);
    t.add(i, i, h - a[i].y);
  }
  // debug("ans=%d\n",ans);
  return ans;
}
int main() {
  init();
  h = readint(), w = readint(), n = readint();
  for (int i = 1; i <= n; i++)
    a[i].x = readint(), a[i].y = readint();
  a[++n] = (point){0, 0};
  a[++n] = (point){h, w};
  // debug("233\n");
  int ans = work();
  // debug("233\n");
  swap(h, w);
  for (int i = 1; i <= n; i++)
    swap(a[i].x, a[i].y);
  ans = max(ans, work());
  printf("%d", ans * 2);
}