Problem p03176 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <tuple>
#include <vector>
using namespace std;
#define INF 1LL << 62
#define MAX 1100000
#define MOD 1000000007
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<pair<int, int>, int> p;
typedef pair<pair<int, int>, int> p;
#define bit(n, k) ((n >> k) & 1) /*nのk bit目*/
#define rad_to_deg(rad) (((rad) / 2 / M_PI) * 360)
//__builtin_popcount(S)

// https://kyopro-friends.hatenablog.com/entry/2019/01/12/231035

const int MAX_N = 210000;

// セグメント木を持つグローバル配列
ll n;
ll dat[2 * MAX_N - 1];

// 初期化
void init(ll n_) {
  // 簡単のために要素数を2のべき乗に
  n = 1;
  while (n < n_)
    n *= 2;

  // 全ての値をINT_MAXに
  for (int i = 0; i < 2 * n - 1; i++)
    dat[i] = -1;
}

// k番目の値(0-indexed)をaに変更
void update(int k, ll a) {
  // 葉の節点
  k += n - 1;
  dat[k] = a;
  // 登りながら更新
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
}

//[a,b)の最小値を求める
// 後ろの方の引数は、計算の簡単のための引数
// ｋは接点の番号、l,rはその接点が[l,r)に対応づいていることを表す
// したがって、外からはquery(a,b,0,0,n)として呼ぶ
ll query(int a, int b, int k, int l, int r) {
  //[a,b)と[l,r)が交差しなければ,INT_MAX
  if (r <= a || b <= l)
    return -1;

  //[a,b)が[l,r)を完全に含んでいれば、この節点の値
  if (a <= l && r <= b)
    return dat[k];
  else {
    // そうでなければ、２つの子の最小値
    ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
}

int main() {
  int N;
  cin >> N;
  int h[210000];
  ll a[210000];
  init(N);
  for (int i = 0; i < N; i++) {
    cin >> h[i];
    h[i]--;
  }
  for (int i = 0; i < N; i++)
    cin >> a[i];

  for (int i = 0; i < N; i++) {
    ll x = query(0, h[i], 0, 0, n);
    // cout<<i<<" "<<x<<endl;
    if (x < 0)
      x = 0;
    update(h[i], x + a[i]);
  }
  cout << query(0, N + 1, 0, 0, n) << endl;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <tuple>
#include <vector>
using namespace std;
#define INF 1LL << 62
#define MAX 1100000
#define MOD 1000000007
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<pair<int, int>, int> p;
typedef pair<pair<int, int>, int> p;
#define bit(n, k) ((n >> k) & 1) /*nのk bit目*/
#define rad_to_deg(rad) (((rad) / 2 / M_PI) * 360)
//__builtin_popcount(S)

// https://kyopro-friends.hatenablog.com/entry/2019/01/12/231035

const int MAX_N = 420000;

// セグメント木を持つグローバル配列
ll n;
ll dat[2 * MAX_N - 1];

// 初期化
void init(ll n_) {
  // 簡単のために要素数を2のべき乗に
  n = 1;
  while (n < n_)
    n *= 2;

  // 全ての値をINT_MAXに
  for (int i = 0; i < 2 * n - 1; i++)
    dat[i] = -1;
}

// k番目の値(0-indexed)をaに変更
void update(int k, ll a) {
  // 葉の節点
  k += n - 1;
  dat[k] = a;
  // 登りながら更新
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = max(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
}

//[a,b)の最小値を求める
// 後ろの方の引数は、計算の簡単のための引数
// ｋは接点の番号、l,rはその接点が[l,r)に対応づいていることを表す
// したがって、外からはquery(a,b,0,0,n)として呼ぶ
ll query(int a, int b, int k, int l, int r) {
  //[a,b)と[l,r)が交差しなければ,INT_MAX
  if (r <= a || b <= l)
    return -1;

  //[a,b)が[l,r)を完全に含んでいれば、この節点の値
  if (a <= l && r <= b)
    return dat[k];
  else {
    // そうでなければ、２つの子の最小値
    ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
}

int main() {
  int N;
  cin >> N;
  int h[210000];
  ll a[210000];
  init(N);
  for (int i = 0; i < N; i++) {
    cin >> h[i];
    h[i]--;
  }
  for (int i = 0; i < N; i++)
    cin >> a[i];

  for (int i = 0; i < N; i++) {
    ll x = query(0, h[i], 0, 0, n);
    // cout<<i<<" "<<x<<endl;
    if (x < 0)
      x = 0;
    update(h[i], x + a[i]);
  }
  cout << query(0, N + 1, 0, 0, n) << endl;
}