Problem p03176 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define ls(x) x << 1
#define rs(x) x << 1 | 1
#define ll long long
#define tree ans
#define rep(i, a, b) for (int i = a; i <= b; i++)
void read(int &x) {
  x = 0;
  int flag = 1;
  char ch = ' ';
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      flag = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  x *= flag;
}
void read(ll &x) {
  x = 0;
  int flag = 1;
  char ch = ' ';
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      flag = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  x *= flag;
}
using namespace std;
const int maxn = 100010;
int n, h[maxn], a[maxn];
ll ans[maxn << 2], dp[maxn], tag[maxn << 2];
void push_up(int p) { ans[p] = max(ans[ls(p)], ans[rs(p)]); }
void change(int p, ll x) {
  ans[p] = max(ans[p], x);
  tag[p] = max(tag[p], x);
}
void push_down(int p, int l, int r) {
  change(ls(p), tag[p]), change(rs(p), tag[p]);
  tag[p] = 0;
}
ll query(int p, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr)
    return ans[p];
  if (tag[p])
    push_down(p, l, r);
  int mid = (l + r) >> 1;
  ll ret = 0;
  if (ql <= mid)
    ret = max(ret, query(ls(p), l, mid, ql, qr));
  if (qr > mid)
    ret = max(ret, query(rs(p), mid + 1, r, ql, qr));
  return ret;
}
void update(int p, int l, int r, int ql, int qr, ll x) {
  if (ql <= l && r <= qr) {
    change(p, x);
    return;
  }
  if (tag[p])
    push_down(p, l, r);
  int mid = (l + r) >> 1;
  if (ql <= mid)
    update(ls(p), l, mid, ql, qr, x);
  if (qr > mid)
    update(rs(p), mid + 1, r, ql, qr, x);
  push_up(p);
}
int main() {
  read(n);
  rep(i, 1, n) read(h[i]);
  rep(i, 1, n) read(a[i]);
  ll ans = 0;
  rep(i, 1, n) {
    ll tmp = h[i] == 1 ? 0 : query(1, 1, n, 1, h[i] - 1);
    dp[i] = tmp + a[i];
    ans = max(ans, dp[i]);
    update(1, 1, n, h[i], n, dp[i]);
  }
  printf("%lld\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define ls(x) x << 1
#define rs(x) x << 1 | 1
#define ll long long
#define tree ans
#define rep(i, a, b) for (int i = a; i <= b; i++)
void read(int &x) {
  x = 0;
  int flag = 1;
  char ch = ' ';
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      flag = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  x *= flag;
}
void read(ll &x) {
  x = 0;
  int flag = 1;
  char ch = ' ';
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      flag = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  x *= flag;
}
using namespace std;
const int maxn = 200010;
int n, h[maxn], a[maxn];
ll ans[maxn << 2], dp[maxn], tag[maxn << 2];
void push_up(int p) { ans[p] = max(ans[ls(p)], ans[rs(p)]); }
void change(int p, ll x) {
  ans[p] = max(ans[p], x);
  tag[p] = max(tag[p], x);
}
void push_down(int p, int l, int r) {
  change(ls(p), tag[p]), change(rs(p), tag[p]);
  tag[p] = 0;
}
ll query(int p, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr)
    return ans[p];
  if (tag[p])
    push_down(p, l, r);
  int mid = (l + r) >> 1;
  ll ret = 0;
  if (ql <= mid)
    ret = max(ret, query(ls(p), l, mid, ql, qr));
  if (qr > mid)
    ret = max(ret, query(rs(p), mid + 1, r, ql, qr));
  return ret;
}
void update(int p, int l, int r, int ql, int qr, ll x) {
  if (ql <= l && r <= qr) {
    change(p, x);
    return;
  }
  if (tag[p])
    push_down(p, l, r);
  int mid = (l + r) >> 1;
  if (ql <= mid)
    update(ls(p), l, mid, ql, qr, x);
  if (qr > mid)
    update(rs(p), mid + 1, r, ql, qr, x);
  push_up(p);
}
int main() {
  read(n);
  rep(i, 1, n) read(h[i]);
  rep(i, 1, n) read(a[i]);
  ll ans = 0;
  rep(i, 1, n) {
    ll tmp = h[i] == 1 ? 0 : query(1, 1, n, 1, h[i] - 1);
    dp[i] = tmp + a[i];
    ans = max(ans, dp[i]);
    update(1, 1, n, h[i], n, dp[i]);
  }
  printf("%lld\n", ans);
  return 0;
}