Problem p03176 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>

#define MAX_N (200000)
// #define NUM_ELEM (1 << 18)
#define NUM_ELEM (1 << 4)
#define SIZE_BUF (2 * NUM_ELEM - 1)
#define INF (1000000000000000000L)

using namespace std;

long buf[SIZE_BUF];

void st_init() {
  for (int i = 0; i < SIZE_BUF; i++) {
    buf[i] = 0;
  }
}

void st_update(long k, long v) {
  long cur = NUM_ELEM - 1 + k;
  buf[cur] = v;
  while (cur > 0) {
    const long par = (cur - 1) / 2;
    const long chl = 2 * par + 1, chr = 2 * par + 2;
    buf[par] = max(buf[chl], buf[chr]);
    cur = par;
  }
}

void st_print() {
  for (int k = 1; k <= NUM_ELEM; k *= 2) {
    for (int i = 0; i < k; i++) {
      printf("%ld ", buf[k - 1 + i]);
    }
    printf("\n");
  }
}

long st_query_r(long queryb, long querye, long cur, long curb, long cure) {
  if (queryb >= cure || querye <= curb) { // no intersection
    return 0;
  } else if (queryb <= curb && querye >= cure) { // current section included
    return buf[cur];
  } else { // currect section includes query
    const long chl = 2 * cur + 1, chr = 2 * cur + 2;
    const long m = (curb + cure) / 2;
    return max(st_query_r(queryb, querye, chl, curb, m),
               st_query_r(queryb, querye, chr, m, cure));
  }
}

long st_query(long queryb, long querye) {
  return st_query_r(queryb, querye, 0, 0, NUM_ELEM);
}

int main() {
  // read inputs
  long N, hs[MAX_N], as[MAX_N];
  scanf("%ld", &N);
  for (long i = 0; i < N; i++) {
    scanf("%ld", &hs[i]);
    hs[i]--; // NOTE : modified input
  }
  for (long i = 0; i < N; i++) {
    scanf("%ld", &as[i]);
  }

  // solve dp
  // initialize
  st_init();
  // update
  for (long i = N - 1; i >= 0; i--) {
    const long h = hs[i], a = as[i];
    const long dp = a + st_query(h + 1, N);
    // st_print();
    // printf("i = %ld, dps[i] = %ld\n", i, dp);
    st_update(h, dp);
  }
  printf("%ld\n", st_query(0, N));
}

Fixed submission:
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>

#define MAX_N (200000)
#define NUM_ELEM (1 << 18)
// #define NUM_ELEM (1 << 4)
#define SIZE_BUF (2 * NUM_ELEM - 1)
#define INF (1000000000000000000L)

using namespace std;

long buf[SIZE_BUF];

void st_init() {
  for (int i = 0; i < SIZE_BUF; i++) {
    buf[i] = 0;
  }
}

void st_update(long k, long v) {
  long cur = NUM_ELEM - 1 + k;
  buf[cur] = v;
  while (cur > 0) {
    const long par = (cur - 1) / 2;
    const long chl = 2 * par + 1, chr = 2 * par + 2;
    buf[par] = max(buf[chl], buf[chr]);
    cur = par;
  }
}

void st_print() {
  for (int k = 1; k <= NUM_ELEM; k *= 2) {
    for (int i = 0; i < k; i++) {
      printf("%ld ", buf[k - 1 + i]);
    }
    printf("\n");
  }
}

long st_query_r(long queryb, long querye, long cur, long curb, long cure) {
  if (queryb >= cure || querye <= curb) { // no intersection
    return 0;
  } else if (queryb <= curb && querye >= cure) { // current section included
    return buf[cur];
  } else { // currect section includes query
    const long chl = 2 * cur + 1, chr = 2 * cur + 2;
    const long m = (curb + cure) / 2;
    return max(st_query_r(queryb, querye, chl, curb, m),
               st_query_r(queryb, querye, chr, m, cure));
  }
}

long st_query(long queryb, long querye) {
  return st_query_r(queryb, querye, 0, 0, NUM_ELEM);
}

int main() {
  // read inputs
  long N, hs[MAX_N], as[MAX_N];
  scanf("%ld", &N);
  for (long i = 0; i < N; i++) {
    scanf("%ld", &hs[i]);
    hs[i]--; // NOTE : modified input
  }
  for (long i = 0; i < N; i++) {
    scanf("%ld", &as[i]);
  }

  // solve dp
  // initialize
  st_init();
  // update
  for (long i = N - 1; i >= 0; i--) {
    const long h = hs[i], a = as[i];
    const long dp = a + st_query(h + 1, N);
    // st_print();
    // printf("i = %ld, dps[i] = %ld\n", i, dp);
    st_update(h, dp);
  }
  printf("%ld\n", st_query(0, N));
}