Problem p03176 (C++)

Buggy submission (status: Runtime Error):
#include <cstdio>
#include <iostream>
#define MAXN 100500
using namespace std;
int a[MAXN];
int h[MAXN];
long long ans[MAXN];
int n;
long long answer;

struct tree {
  int l;
  int r;
  long long maks;
  int left_child;
  int right_child;
};
tree g[4 * MAXN];

void create_tree(int v) {
  if (g[v].l == g[v].r) {
    return;
  }
  g[v].left_child = v * 2 + 1;
  g[v * 2 + 1].l = g[v].l;
  g[v * 2 + 1].r = (g[v].r + g[v].l) / 2;
  create_tree(2 * v + 1);
  g[v].right_child = v * 2 + 2;
  g[v * 2 + 2].l = (g[v].r + g[v].l) / 2 + 1;
  g[v * 2 + 2].r = g[v].r;
  create_tree(2 * v + 2);
}

void add_tree(int v, long long k) {
  int now = 0;
  while (g[now].l != g[now].r) {
    g[now].maks = max(g[now].maks, k);
    if (v >= g[g[now].left_child].l && v <= g[g[now].left_child].r) {
      now = g[now].left_child;
    } else {
      now = g[now].right_child;
    }
  }
  g[now].maks = max(g[now].maks, k);
}
long long find_tree(int l, int r, int v) {
  // printf("find_tree: l=%i r=%i v=%i\n", l, r, v);
  if (g[v].r < l || r < g[v].l) {
    // printf("  find_tree: v=%i returns 0\n", v);
    return 0;
  }
  // if (g[v].l > l && g[v].r < r){
  if (l <= g[v].l && g[v].r <= r) {
    // printf("  find_tree: v=%i returns %i\n", v, g[v].maks);
    return g[v].maks;
  }
  long long tmp =
      max(find_tree(l, r, g[v].left_child), find_tree(l, r, g[v].right_child));
  // printf("  find_tree: v=%i returns %i\n", v, tmp);
  return tmp;
}

void dbg(int v, long long k) {
  if (g[v].l != g[v].r) {
    dbg(g[v].right_child, k + 1);
  }
  for (int i = 1; i <= k; i++) {
    cout << "  ";
  }
  cout << g[v].maks << endl;
  if (g[v].l != g[v].r) {
    dbg(g[v].left_child, k + 1);
  }
}

int main() {
  cin >> n;
  g[0].l = 1;
  g[0].r = n;
  create_tree(0);
  for (int i = 1; i <= n; i++) {
    cin >> h[i];
  }
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  ans[1] = a[1];
  add_tree(h[1], ans[1]);
  for (int i = 2; i <= n; i++) {
    // dbg(0, 0);
    // cout << endl;
    // cout << endl;
    /*answer = 0;
    for (int j = 1; j < i; j++){
        if (h[i] > h[j] && answer < ans[j]){
           answer = ans[j];
        }
    }*/
    // printf("find_tree(1, %i - 1) = %i\n", h[i], find_tree(1, h[i] - 1, 0));
    ans[i] = a[i] + find_tree(1, h[i] - 1, 0);

    add_tree(h[i], ans[i]);
  }
  long long answer = 0;
  for (int i = 1; i <= n; i++) {
    // cout << ans[i] << ' ';
    if (answer < ans[i])
      answer = ans[i];
  }
  // cout << endl;
  cout << answer;
}

Fixed submission:
#include <cstdio>
#include <iostream>
#define MAXN 200500
using namespace std;
int a[MAXN];
int h[MAXN];
long long ans[MAXN];
int n;
long long answer;

struct tree {
  int l;
  int r;
  long long maks;
  int left_child;
  int right_child;
};
tree g[4 * MAXN];

void create_tree(int v) {
  if (g[v].l == g[v].r) {
    return;
  }
  g[v].left_child = v * 2 + 1;
  g[v * 2 + 1].l = g[v].l;
  g[v * 2 + 1].r = (g[v].r + g[v].l) / 2;
  create_tree(2 * v + 1);
  g[v].right_child = v * 2 + 2;
  g[v * 2 + 2].l = (g[v].r + g[v].l) / 2 + 1;
  g[v * 2 + 2].r = g[v].r;
  create_tree(2 * v + 2);
}

void add_tree(int v, long long k) {
  int now = 0;
  while (g[now].l != g[now].r) {
    g[now].maks = max(g[now].maks, k);
    if (v >= g[g[now].left_child].l && v <= g[g[now].left_child].r) {
      now = g[now].left_child;
    } else {
      now = g[now].right_child;
    }
  }
  g[now].maks = max(g[now].maks, k);
}
long long find_tree(int l, int r, int v) {
  // printf("find_tree: l=%i r=%i v=%i\n", l, r, v);
  if (g[v].r < l || r < g[v].l) {
    // printf("  find_tree: v=%i returns 0\n", v);
    return 0;
  }
  // if (g[v].l > l && g[v].r < r){
  if (l <= g[v].l && g[v].r <= r) {
    // printf("  find_tree: v=%i returns %i\n", v, g[v].maks);
    return g[v].maks;
  }
  long long tmp =
      max(find_tree(l, r, g[v].left_child), find_tree(l, r, g[v].right_child));
  // printf("  find_tree: v=%i returns %i\n", v, tmp);
  return tmp;
}

void dbg(int v, long long k) {
  if (g[v].l != g[v].r) {
    dbg(g[v].right_child, k + 1);
  }
  for (int i = 1; i <= k; i++) {
    cout << "  ";
  }
  cout << g[v].maks << endl;
  if (g[v].l != g[v].r) {
    dbg(g[v].left_child, k + 1);
  }
}

int main() {
  cin >> n;
  g[0].l = 1;
  g[0].r = n;
  create_tree(0);
  for (int i = 1; i <= n; i++) {
    cin >> h[i];
  }
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  ans[1] = a[1];
  add_tree(h[1], ans[1]);
  for (int i = 2; i <= n; i++) {
    // dbg(0, 0);
    // cout << endl;
    // cout << endl;
    /*answer = 0;
    for (int j = 1; j < i; j++){
        if (h[i] > h[j] && answer < ans[j]){
           answer = ans[j];
        }
    }*/
    // printf("find_tree(1, %i - 1) = %i\n", h[i], find_tree(1, h[i] - 1, 0));
    ans[i] = a[i] + find_tree(1, h[i] - 1, 0);

    add_tree(h[i], ans[i]);
  }
  long long answer = 0;
  for (int i = 1; i <= n; i++) {
    // cout << ans[i] << ' ';
    if (answer < ans[i])
      answer = ans[i];
  }
  // cout << endl;
  cout << answer;
}