Problem p03950 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)
using namespace std;

typedef long long ll;

int read() {
  char ch;
  for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())
    ;
  int x = ch - '0';
  for (ch = getchar(); ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return x;
}

const int N = 3 * 1e5 + 5;

int w, h, n, ta, tb, ans;
struct P {
  int x, y;
} p[N], sta[N], stb[N];
bool cmp(P x, P y) { return x.x < y.x; }

int tr[N << 2], tag[N << 2];

void add(int v, int z) {
  tr[v] += z;
  tag[v] += z;
}

void down(int v) {
  if (tag[v]) {
    add(v << 1, tag[v]);
    add(v << 1 | 1, tag[v]);
    tag[v] = 0;
  }
}

void modify(int v, int l, int r, int x, int y, int z) {
  if (l == x && r == y) {
    add(v, z);
    return;
  }
  int mid = l + r >> 1;
  down(v);
  if (y <= mid)
    modify(v << 1, l, mid, x, y, z);
  else if (x > mid)
    modify(v << 1 | 1, mid + 1, r, x, y, z);
  else
    modify(v << 1, l, mid, x, mid, z),
        modify(v << 1 | 1, mid + 1, r, mid + 1, y, z);
  tr[v] = max(tr[v << 1], tr[v << 1 | 1]);
}

void solve() {
  sort(p + 1, p + n + 1, cmp);
  fo(i, 1, n << 2) tr[i] = tag[i] = 0;
  ta = tb = 0;
  fo(i, 1, n) {
    if (p[i].y <= h / 2) {
      int la = i - 1;
      while (ta && sta[ta].y < p[i].y) {
        modify(1, 1, n, sta[ta].x, la, sta[ta].y - p[i].y);
        la = sta[ta--].x - 1;
      }
      if (la != i - 1)
        sta[++ta].x = la + 1, sta[ta].y = p[i].y;
    } else {
      int la = i - 1;
      while (tb && stb[tb].y > p[i].y) {
        modify(1, 1, n, stb[tb].x, la, p[i].y - stb[tb].y);
        la = stb[tb--].x - 1;
      }
      if (la != i - 1)
        stb[++tb].x = la + 1, stb[tb].y = p[i].y;
    }
    sta[++ta].x = i;
    sta[ta].y = 0;
    stb[++tb].x = i;
    stb[tb].y = h;
    modify(1, 1, n, i, i, h - p[i].x);
    ans = max(ans, tr[1] + p[i + 1].x);
  }
}

int main() {
  freopen("paint.in", "r", stdin);
  freopen("paint.out", "w", stdout);
  w = read();
  h = read();
  n = read();
  fo(i, 1, n) {
    p[i].x = read();
    p[i].y = read();
  }
  p[++n].x = 0;
  p[n].y = 0;
  p[++n].x = w;
  p[n].y = h;
  solve();
  fo(i, 1, n) swap(p[i].x, p[i].y);
  swap(w, h);
  solve();
  printf("%d\n", ans * 2);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)
using namespace std;

typedef long long ll;

int read() {
  char ch;
  for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())
    ;
  int x = ch - '0';
  for (ch = getchar(); ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return x;
}

const int N = 3 * 1e5 + 5;

int w, h, n, ta, tb, ans;
struct P {
  int x, y;
} p[N], sta[N], stb[N];
bool cmp(P x, P y) { return x.x < y.x; }

int tr[N << 2], tag[N << 2];

void add(int v, int z) {
  tr[v] += z;
  tag[v] += z;
}

void down(int v) {
  if (tag[v]) {
    add(v << 1, tag[v]);
    add(v << 1 | 1, tag[v]);
    tag[v] = 0;
  }
}

void modify(int v, int l, int r, int x, int y, int z) {
  if (l == x && r == y) {
    add(v, z);
    return;
  }
  int mid = l + r >> 1;
  down(v);
  if (y <= mid)
    modify(v << 1, l, mid, x, y, z);
  else if (x > mid)
    modify(v << 1 | 1, mid + 1, r, x, y, z);
  else
    modify(v << 1, l, mid, x, mid, z),
        modify(v << 1 | 1, mid + 1, r, mid + 1, y, z);
  tr[v] = max(tr[v << 1], tr[v << 1 | 1]);
}

void solve() {
  sort(p + 1, p + n + 1, cmp);
  fo(i, 1, n << 2) tr[i] = tag[i] = 0;
  ta = tb = 0;
  fo(i, 1, n) {
    if (p[i].y <= h / 2) {
      int la = i - 1;
      while (ta && sta[ta].y < p[i].y) {
        modify(1, 1, n, sta[ta].x, la, sta[ta].y - p[i].y);
        la = sta[ta--].x - 1;
      }
      if (la != i - 1)
        sta[++ta].x = la + 1, sta[ta].y = p[i].y;
    } else {
      int la = i - 1;
      while (tb && stb[tb].y > p[i].y) {
        modify(1, 1, n, stb[tb].x, la, p[i].y - stb[tb].y);
        la = stb[tb--].x - 1;
      }
      if (la != i - 1)
        stb[++tb].x = la + 1, stb[tb].y = p[i].y;
    }
    sta[++ta].x = i;
    sta[ta].y = 0;
    stb[++tb].x = i;
    stb[tb].y = h;
    modify(1, 1, n, i, i, h - p[i].x);
    ans = max(ans, tr[1] + p[i + 1].x);
  }
}

int main() {
  w = read();
  h = read();
  n = read();
  fo(i, 1, n) {
    p[i].x = read();
    p[i].y = read();
  }
  p[++n].x = 0;
  p[n].y = 0;
  p[++n].x = w;
  p[n].y = h;
  solve();
  fo(i, 1, n) swap(p[i].x, p[i].y);
  swap(w, h);
  solve();
  printf("%d\n", ans * 2);
  return 0;
}