Problem p03176 (C++)

Buggy submission (status: Runtime Error):
// csjosh

#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp> //required
// #include <ext/pb_ds/tree_policy.hpp> //required
// using namespace __gnu_pbds; //required
using namespace std;

#define ll long long
#define loop(x) for (int i = 0; i < x; i++)

#define llu unsigned long long
#define pb push_back
#define sc(x) scanf("%lld", &x)
#define pr(x) printf("%lld\n", x)
#define dd fflush(stdout)
#define what_is(x) cerr << #x << " is " << x << endl;
#define IOS                                                                    \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define mt make_tuple // use tie
#define eb emplace_back
typedef tuple<int, int, int> State; // use in dijkstra
// ll mod=1e9+7;
// ll power(ll x,ll y,ll mod){
//  ll ans=1;
//  while(y>0){
//   if(y&1){
//     ans=ans*x;
//   }
//   x=x*x;
//   y=y/2;
//  }
//  return ans;
// }

// typedef tree<
// pair<int, int>,
// null_type,
// less<pair<int, int>>,
// rb_tree_tag,
// tree_order_statistics_node_update> ordered_set;

int n;
ll a[100006];
ll h[100006];
ll tree[4 * 1000005];
ll update(int root, int x, int start, int end, ll val) {
  if ((x < start) || (x > end))
    return 0;
  if (start == end) {
    tree[root] = max(tree[root], val);
    return tree[root];
  }
  ll p1 = 0, p2 = 0;
  int mid = (start + end) / 2;
  p1 = update(2 * root, x, start, mid, val);

  p2 = update(2 * root + 1, x, mid + 1, end, val);
  return tree[root] = max(tree[root], max(p1, p2));
}
ll query(int root, int l, int r, int start, int end) {
  if (start > end)
    return 0;
  if (r < start || l > end)
    return 0;
  if (l <= start && r >= end)
    return tree[root];

  int mid = (start + end) / 2;
  ll p1 = query(2 * root, l, r, start, mid);
  ll p2 = query(2 * root + 1, l, r, mid + 1, end);
  return max(p1, p2);
}
int main() {
  IOS;

  cin >> n;
  // memset(bit,0,sizeof bit);
  loop(n) cin >> h[i + 1];
  loop(n) cin >> a[i + 1];
  // first use of segment trees
  ll maxsum = 0;
  for (int i = 1; i <= n; i++) {
    maxsum = query(1, 1, h[i], 1, n) + a[i];
    update(1, h[i], 1, n, maxsum);
  }
  cout << query(1, 1, n, 1, n) << endl;
}


Fixed submission:
// csjosh

#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp> //required
// #include <ext/pb_ds/tree_policy.hpp> //required
// using namespace __gnu_pbds; //required
using namespace std;

#define ll long long
#define loop(x) for (int i = 0; i < x; i++)

#define llu unsigned long long
#define pb push_back
#define sc(x) scanf("%lld", &x)
#define pr(x) printf("%lld\n", x)
#define dd fflush(stdout)
#define what_is(x) cerr << #x << " is " << x << endl;
#define IOS                                                                    \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define mt make_tuple // use tie
#define eb emplace_back
typedef tuple<int, int, int> State; // use in dijkstra
// ll mod=1e9+7;
// ll power(ll x,ll y,ll mod){
//  ll ans=1;
//  while(y>0){
//   if(y&1){
//     ans=ans*x;
//   }
//   x=x*x;
//   y=y/2;
//  }
//  return ans;
// }

// typedef tree<
// pair<int, int>,
// null_type,
// less<pair<int, int>>,
// rb_tree_tag,
// tree_order_statistics_node_update> ordered_set;

int n;
ll a[400006];
ll h[400006];
ll tree[4 * 1000005];
ll update(int root, int x, int start, int end, ll val) {
  if ((x < start) || (x > end))
    return 0;
  if (start == end) {
    tree[root] = max(tree[root], val);
    return tree[root];
  }
  ll p1 = 0, p2 = 0;
  int mid = (start + end) / 2;
  p1 = update(2 * root, x, start, mid, val);

  p2 = update(2 * root + 1, x, mid + 1, end, val);
  return tree[root] = max(tree[root], max(p1, p2));
}
ll query(int root, int l, int r, int start, int end) {
  if (start > end)
    return 0;
  if (r < start || l > end)
    return 0;
  if (l <= start && r >= end)
    return tree[root];

  int mid = (start + end) / 2;
  ll p1 = query(2 * root, l, r, start, mid);
  ll p2 = query(2 * root + 1, l, r, mid + 1, end);
  return max(p1, p2);
}
int main() {
  IOS;

  cin >> n;
  // memset(bit,0,sizeof bit);
  loop(n) cin >> h[i + 1];
  loop(n) cin >> a[i + 1];
  // first use of segment trees
  ll maxsum = 0;
  for (int i = 1; i <= n; i++) {
    maxsum = query(1, 1, h[i], 1, n) + a[i];
    update(1, h[i], 1, n, maxsum);
  }
  cout << query(1, 1, n, 1, n) << endl;
}