Problem p03950 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <stack>
#include <stdio.h>
#include <vector>
#define INF 2000000000
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
const int MAXN = 100005;
int num[MAXN], X[MAXN], Y[MAXN];
int W, H, n, cnt;
struct Tree {
  int maxNum, lazy;
} tree[MAXN << 2];
void pushUp(int rt) {
  tree[rt].maxNum = max(tree[rt << 1].maxNum, tree[rt << 1 | 1].maxNum);
}
void pushDown(int rt) {
  if (tree[rt].lazy) {
    tree[rt << 1].maxNum += tree[rt].lazy;
    tree[rt << 1].lazy += tree[rt].lazy;

    tree[rt << 1 | 1].maxNum += tree[rt].lazy;
    tree[rt << 1 | 1].lazy += tree[rt].lazy;

    tree[rt].lazy = 0;
  }
}
void buildTree(int l, int r, int rt) {
  tree[rt].lazy = 0;
  if (l == r) {
    tree[rt].maxNum = W - num[l - 1];
    return;
  }
  int m = (l + r) >> 1;
  buildTree(lson);
  buildTree(rson);
  pushUp(rt);
}
void update(int ll, int rr, int add, int l, int r, int rt) {
  if (ll > rr)
    return;
  if (ll <= l && r <= rr) {
    tree[rt].lazy += add;
    tree[rt].maxNum += add;
    return;
  }
  pushDown(rt);
  int m = (l + r) >> 1;
  if (ll <= m)
    update(ll, rr, add, lson);
  if (rr > m)
    update(ll, rr, add, rson);
  pushUp(rt);
}
int query(int ll, int rr, int l, int r, int rt) {
  if (ll > rr)
    return -INF;
  if (ll <= l && r <= rr)
    return tree[rt].maxNum;
  pushDown(rt);
  int res = -INF, m = (l + r) >> 1;
  if (ll <= m)
    res = max(res, query(ll, rr, lson));
  if (rr > m)
    res = max(res, query(ll, rr, rson));
  return res;
}

int getPos(int x) { return lower_bound(num, num + cnt, x) - num + 1; }

int solve() {
  vector<pair<int, int>> pts;
  cnt = 0;
  for (int i = 0; i < n; i++) {
    pts.push_back(make_pair(Y[i], X[i]));
    num[cnt++] = Y[i];
  }
  pts.push_back(make_pair(H, 0));
  sort(pts.begin(), pts.end());
  num[cnt++] = 0, num[cnt++] = H;
  sort(num, num + cnt);
  cnt = unique(num, num + cnt) - num;
  buildTree(1, cnt, 1);
  stack<pair<int, int>> up, dn;
  up.push(make_pair(0, W / 2)), dn.push(make_pair(0, W / 2));
  int res = -INF;
  for (int i = 0; i <= n; i++) {
    int x = pts[i].second, y = pts[i].first;
    res = max(res, y + query(1, getPos(y) - 1, 1, cnt, 1));
    // cout << x << " " << y << " " << query(1, getPos(y) - 1, 1, cnt, 1) <<
    // endl;
    if (x <= W / 2) {
      pair<int, int> A = make_pair(y, 0);
      while (x > up.top().second) {
        update(getPos(up.top().first), getPos(A.first) - 1, A.second - x, 1,
               cnt, 1);
        A = up.top();
        up.pop();
      }
      update(getPos(up.top().first), getPos(A.first) - 1, A.second - x, 1, cnt,
             1);
      up.push(pts[i]);
    } else {
      pair<int, int> A = make_pair(y, W);
      while (x < dn.top().second) {
        update(getPos(dn.top().first), getPos(A.first) - 1, x - A.second, 1,
               cnt, 1);
        A = dn.top();
        dn.pop();
      }
      update(getPos(dn.top().first), getPos(A.first) - 1, x - A.second, 1, cnt,
             1);
      dn.push(pts[i]);
    }
  }
  return res;
}

int main() {
  scanf("%d%d%d", &W, &H, &n);
  W *= 2, H *= 2;
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &X[i], &Y[i]);
    X[i] *= 2;
    Y[i] *= 2;
  }
  int ans = -INF;
  for (int k = 0; k < 2; k++) {
    ans = max(ans, solve());
    swap(W, H);
    for (int i = 0; i < n; i++)
      swap(X[i], Y[i]);
  }
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <stack>
#include <stdio.h>
#include <vector>
#define INF 2000000000
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
const int MAXN = 300005;
int num[MAXN], X[MAXN], Y[MAXN];
int W, H, n, cnt;
struct Tree {
  int maxNum, lazy;
} tree[MAXN << 2];
void pushUp(int rt) {
  tree[rt].maxNum = max(tree[rt << 1].maxNum, tree[rt << 1 | 1].maxNum);
}
void pushDown(int rt) {
  if (tree[rt].lazy) {
    tree[rt << 1].maxNum += tree[rt].lazy;
    tree[rt << 1].lazy += tree[rt].lazy;

    tree[rt << 1 | 1].maxNum += tree[rt].lazy;
    tree[rt << 1 | 1].lazy += tree[rt].lazy;

    tree[rt].lazy = 0;
  }
}
void buildTree(int l, int r, int rt) {
  tree[rt].lazy = 0;
  if (l == r) {
    tree[rt].maxNum = W - num[l - 1];
    return;
  }
  int m = (l + r) >> 1;
  buildTree(lson);
  buildTree(rson);
  pushUp(rt);
}
void update(int ll, int rr, int add, int l, int r, int rt) {
  if (ll > rr)
    return;
  if (ll <= l && r <= rr) {
    tree[rt].lazy += add;
    tree[rt].maxNum += add;
    return;
  }
  pushDown(rt);
  int m = (l + r) >> 1;
  if (ll <= m)
    update(ll, rr, add, lson);
  if (rr > m)
    update(ll, rr, add, rson);
  pushUp(rt);
}
int query(int ll, int rr, int l, int r, int rt) {
  if (ll > rr)
    return -INF;
  if (ll <= l && r <= rr)
    return tree[rt].maxNum;
  pushDown(rt);
  int res = -INF, m = (l + r) >> 1;
  if (ll <= m)
    res = max(res, query(ll, rr, lson));
  if (rr > m)
    res = max(res, query(ll, rr, rson));
  return res;
}

int getPos(int x) { return lower_bound(num, num + cnt, x) - num + 1; }

int solve() {
  vector<pair<int, int>> pts;
  cnt = 0;
  for (int i = 0; i < n; i++) {
    pts.push_back(make_pair(Y[i], X[i]));
    num[cnt++] = Y[i];
  }
  pts.push_back(make_pair(H, 0));
  sort(pts.begin(), pts.end());
  num[cnt++] = 0, num[cnt++] = H;
  sort(num, num + cnt);
  cnt = unique(num, num + cnt) - num;
  buildTree(1, cnt, 1);
  stack<pair<int, int>> up, dn;
  up.push(make_pair(0, W / 2)), dn.push(make_pair(0, W / 2));
  int res = -INF;
  for (int i = 0; i <= n; i++) {
    int x = pts[i].second, y = pts[i].first;
    res = max(res, y + query(1, getPos(y) - 1, 1, cnt, 1));
    // cout << x << " " << y << " " << query(1, getPos(y) - 1, 1, cnt, 1) <<
    // endl;
    if (x <= W / 2) {
      pair<int, int> A = make_pair(y, 0);
      while (x > up.top().second) {
        update(getPos(up.top().first), getPos(A.first) - 1, A.second - x, 1,
               cnt, 1);
        A = up.top();
        up.pop();
      }
      update(getPos(up.top().first), getPos(A.first) - 1, A.second - x, 1, cnt,
             1);
      up.push(pts[i]);
    } else {
      pair<int, int> A = make_pair(y, W);
      while (x < dn.top().second) {
        update(getPos(dn.top().first), getPos(A.first) - 1, x - A.second, 1,
               cnt, 1);
        A = dn.top();
        dn.pop();
      }
      update(getPos(dn.top().first), getPos(A.first) - 1, x - A.second, 1, cnt,
             1);
      dn.push(pts[i]);
    }
  }
  return res;
}

int main() {
  scanf("%d%d%d", &W, &H, &n);
  W *= 2, H *= 2;
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &X[i], &Y[i]);
    X[i] *= 2;
    Y[i] *= 2;
  }
  int ans = -INF;
  for (int k = 0; k < 2; k++) {
    ans = max(ans, solve());
    swap(W, H);
    for (int i = 0; i < n; i++)
      swap(X[i], Y[i]);
  }
  printf("%d\n", ans);
  return 0;
}