Problem p03176 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
const ull mod = 1e9 + 7;
#define REP(i, n) for (int i = 0; i < (int)n; ++i)

// debug
#define dump(x) cerr << #x << " = " << (x) << endl;
#define debug(x)                                                               \
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ")"                       \
       << " " << __FILE__ << endl;

template <typename T> void vprint(T &v) {
  REP(i, v.size()) { cout << v[i] << " "; }
  cout << endl;
}

typedef ll V;
typedef pair<V, V> pVV;
const V INF_V = LLONG_MAX;
const int ME = 17;
const int N = 1 << ME;
class RMQ_segtree {
public:
  pVV dat[2 * N - 1];
  RMQ_segtree() { REP(i, 2 * N - 1) dat[i] = make_pair(INF_V, -1); }

  void update(int k, V a) {
    // k番目の要素をaに変更
    k += N - 1;
    dat[k] = make_pair(a, k - (N - 1));
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }

  pVV recursion(int a, int b, int k, int l, int r) {
    // 最小値計算用の再帰関数
    if (r <= a || b <= l)
      return make_pair(INF_V, -1);
    if (a <= l && r <= b)
      return dat[k];
    else {
      pVV vl = recursion(a, b, 2 * k + 1, l, (l + r) / 2);
      pVV vr = recursion(a, b, 2 * k + 2, (l + r) / 2, r);
      return min(vl, vr);
    }
  }

  pVV minimum(int a, int b) {
    // 区間[a, b)の最小値
    return recursion(a, b, 0, 0, N);
  }

  void print_val(int a, int b) {
    // 区間[a, b)の値を出力
    for (int i = a; i < b; i++)
      cout << dat[i + N - 1].first << endl;
    cout << endl;
  }
};

int main() {
  ll N;
  cin >> N;
  vector<ll> h(N), a(N);
  REP(i, N) cin >> h[i];
  REP(i, N) cin >> a[i];

  vector<pll> x(N);
  REP(i, N) x[i].first = h[i], x[i].second = i;
  sort(x.begin(), x.end());
  RMQ_segtree rs;
  REP(i, N) {
    ll tmp;
    if (x[i].second == 0)
      tmp = 0;
    else
      tmp = -rs.minimum(0, x[i].second).first;
    if (tmp == -INF_V)
      tmp = 0;
    rs.update(x[i].second, -tmp - a[x[i].second]);
  }
  ll res = -1;
  REP(i, N) res = max(res, -rs.minimum(i, i + 1).first);
  cout << res << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
const ull mod = 1e9 + 7;
#define REP(i, n) for (int i = 0; i < (int)n; ++i)

// debug
#define dump(x) cerr << #x << " = " << (x) << endl;
#define debug(x)                                                               \
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ")"                       \
       << " " << __FILE__ << endl;

template <typename T> void vprint(T &v) {
  REP(i, v.size()) { cout << v[i] << " "; }
  cout << endl;
}

typedef ll V;
typedef pair<V, V> pVV;
const V INF_V = LLONG_MAX;
const int ME = 18;
const int N = 1 << ME;
class RMQ_segtree {
public:
  pVV dat[2 * N - 1];
  RMQ_segtree() { REP(i, 2 * N - 1) dat[i] = make_pair(INF_V, -1); }

  void update(int k, V a) {
    // k番目の要素をaに変更
    k += N - 1;
    dat[k] = make_pair(a, k - (N - 1));
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[2 * k + 1], dat[2 * k + 2]);
    }
  }

  pVV recursion(int a, int b, int k, int l, int r) {
    // 最小値計算用の再帰関数
    if (r <= a || b <= l)
      return make_pair(INF_V, -1);
    if (a <= l && r <= b)
      return dat[k];
    else {
      pVV vl = recursion(a, b, 2 * k + 1, l, (l + r) / 2);
      pVV vr = recursion(a, b, 2 * k + 2, (l + r) / 2, r);
      return min(vl, vr);
    }
  }

  pVV minimum(int a, int b) {
    // 区間[a, b)の最小値
    return recursion(a, b, 0, 0, N);
  }

  void print_val(int a, int b) {
    // 区間[a, b)の値を出力
    for (int i = a; i < b; i++)
      cout << dat[i + N - 1].first << endl;
    cout << endl;
  }
};

int main() {
  ll N;
  cin >> N;
  vector<ll> h(N), a(N);
  REP(i, N) cin >> h[i];
  REP(i, N) cin >> a[i];

  vector<pll> x(N);
  REP(i, N) x[i].first = h[i], x[i].second = i;
  sort(x.begin(), x.end());
  RMQ_segtree rs;
  REP(i, N) {
    ll tmp;
    if (x[i].second == 0)
      tmp = 0;
    else
      tmp = -rs.minimum(0, x[i].second).first;
    if (tmp == -INF_V)
      tmp = 0;
    rs.update(x[i].second, -tmp - a[x[i].second]);
  }
  ll res = -1;
  REP(i, N) res = max(res, -rs.minimum(i, i + 1).first);
  cout << res << endl;
  return 0;
}