Problem p02648 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;

constexpr int32_t MAX_BIT = (1ull << 10);
constexpr int32_t MAX_WEIGHT = 1e5;

int32_t dp[MAX_BIT + 1][MAX_WEIGHT + 1];

int main() {
  int32_t N;
  cin >> N;
  vector<int32_t> V(N + 1), W(N + 1);
  for (int32_t i = 1; i <= N; i++) {
    cin >> V[i] >> W[i];
    //        V[i] = W[i] = i;
  }

  int32_t Q;
  cin >> Q;
  vector<int32_t> v(Q), L(Q);
  for (int32_t i = 0; i < Q; i++) {
    cin >> v[i] >> L[i];
  }

  // 半分全列挙
  int32_t lb = min(N, MAX_BIT);

  // dp[i][j] := i番目のノードにおいて残り容量がjであるときの最大価値
  // 1のところを初期化
  for (int32_t j = W[1]; j <= MAX_WEIGHT; j++) {
    dp[1][j] = V[1];
  }

  for (int32_t i = 2; i <= lb; i++) {
    for (int32_t j = 0; j <= MAX_WEIGHT; j++) {
      // 選ばない場合
      dp[i][j] = max(dp[i][j], dp[i / 2][j]);

      // 選ぶ場合
      if (j - W[i] >= 0) {
        dp[i][j] = max(dp[i][j], dp[i / 2][j - W[i]] + V[i]);
      }
    }
  }

  // クエリを解く
  for (int32_t i = 0; i < Q; i++) {
    // スタート位置が基準より前だったらそのまま答えて終わり
    if (v[i] <= lb) {
      cout << dp[v[i]][L[i]] << endl;
      continue;
    }

    // そうでなかったらlbに入るまでを全探索
    vector<int32_t> curr_v, curr_w;
    int32_t node = v[i];
    for (; node > lb; node /= 2) {
      curr_v.push_back(V[node]);
      curr_w.push_back(W[node]);
    }

    int32_t ans = 0;
    int32_t max_bit = (1ull << curr_v.size());
    for (int32_t j = 0; j < max_bit; j++) {
      int32_t curr_value = 0, curr_weight = 0;
      for (int32_t k = 0; k < curr_v.size(); k++) {
        if (j & (1ull << k)) {
          curr_value += curr_v[k];
          curr_weight += curr_w[k];
        }
      }

      if (curr_weight > L[i]) {
        continue;
      }

      ans = max(ans,
                curr_value +
                    (L[i] == curr_weight ? 0 : dp[node][L[i] - curr_weight]));
    }

    cout << ans << endl;
  }
}

Error: -11

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

constexpr int32_t MAX_BIT = (1ull << 10);
constexpr int32_t MAX_WEIGHT = 1e5;

int32_t dp[MAX_BIT + 1][MAX_WEIGHT];

int main() {
  int32_t N;
  cin >> N;
  vector<int32_t> V(N + 1), W(N + 1);
  for (int32_t i = 1; i <= N; i++) {
    cin >> V[i] >> W[i];
  }

  int32_t Q;
  cin >> Q;
  vector<int32_t> v(Q), L(Q);
  for (int32_t i = 0; i < Q; i++) {
    cin >> v[i] >> L[i];
  }

  // 半分全列挙
  int32_t lb = min(N, MAX_BIT);

  // dp[i][j] := i番目のノードにおいて残り容量がjであるときの最大価値
  // 1のところを初期化
  for (int32_t j = W[1]; j <= MAX_WEIGHT; j++) {
    dp[1][j] = V[1];
  }

  for (int32_t i = 1; i <= lb; i++) {
    for (int32_t j = 0; j <= MAX_WEIGHT; j++) {
      // 選ばない場合
      dp[i][j] = max(dp[i][j], dp[i / 2][j]);

      // 選ぶ場合
      if (j - W[i] >= 0) {
        dp[i][j] = max(dp[i][j], dp[i / 2][j - W[i]] + V[i]);
      }
    }
  }

  // クエリを解く
  for (int32_t i = 0; i < Q; i++) {
    // スタート位置が基準より前だったらそのまま答えて終わり
    if (v[i] <= lb) {
      cout << dp[v[i]][L[i]] << endl;
      continue;
    }

    assert(false);
    // そうでなかったらlbに入るまでを全探索
    vector<int32_t> curr_v, curr_w;
    int32_t node = v[i];
    for (; node > lb; node /= 2) {
      curr_v.push_back(V[node]);
      curr_w.push_back(W[node]);
    }

    int32_t ans = 0;
    int32_t max_bit = (1ull << curr_v.size());
    for (int32_t j = 0; j < max_bit; j++) {
      int32_t curr_value = 0, curr_weight = 0;
      for (int32_t k = 0; k < curr_v.size(); k++) {
        if (j & (1ull << k)) {
          curr_value += curr_v[k];
          curr_weight += curr_w[k];
        }
      }

      if (curr_weight > L[i]) {
        continue;
      }

      ans = max(ans, curr_value + dp[node][L[i] - curr_weight]);
    }

    cout << ans << endl;
  }
}