Problem p02648 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include "bits/stdc++.h"
using namespace std;
#define REP(i, n) for (ll i = 0; i < n; i++)
#define ll long long
#define MOD 1000000007LL
#define llMAX 9223372036854775807LL
#define llMIN -9223372036854775808LL
using vi = vector<ll>;  // llの1次元の型に vi という別名をつける
using vvi = vector<vi>; // llの2次元の型に vvi という別名をつける

ll n;
ll M = 1e5 + 1;

// bit全探索
vi bt;
void setbit(ll i) {
  bt.clear();
  for (ll tmp = 0; i > 0; i /= 2) {
    if (i % 2 == 1)
      bt.push_back(tmp);
    tmp++;
  }
}

int main() {
  ll ans = 0, q;
  cin >> n;
  n++;
  ll nlg = ceil(log2(n));
  vi V(n), W(n);
  REP(i, n - 1) cin >> V[i + 1] >> W[i + 1];

  cin >> q;
  vi u(q), L(q);
  REP(i, q) cin >> u[i] >> L[i];

  // 上半分
  ll nhi = nlg - (nlg / 2);
  if (nhi == 9)
    nhi = 10;
  vvi data(1LL << nhi, vi(M)); // N * M の2次元配列

  for (ll i = 1; i < (1LL << nhi); i++) {
    for (ll j = 0; j < M; j++) {
      if ((j - W[i]) >= 0) {
        data[i][j] = max(data[i / 2][j - W[i]] + V[i], data[i / 2][j]);
      } else {
        data[i][j] = data[i / 2][j];
      }
    }
  }

  ll uiv[10];
  ll wuiv = 0;

  // 下半分
  for (ll loop = 0; loop < q; loop++) {
    ll uidx = u[loop];
    if (uidx < (1LL << nhi)) {
      cout << data[uidx][L[loop]] << endl;
    } else { // 上＋下
      ll maxval = 0;
      // vi uiv;
      ll nn = 0;
      wuiv = 0;
      for (;; uidx /= 2) {
        if (uidx < (1LL << nhi))
          break;
        uiv[wuiv] = uidx;
        wuiv++;
        nn++;
      }

      ll bn = 1 << nn;
      for (ll i = 0; i < bn; i++) {
        setbit(i);
        ll tmpw = 0;
        ll tmpv = 0;
        /*
        for(ll j=0;j<nn;j++){
          if (i&(1<<j)){
            tmpv+=V[uiv[j]];
            tmpw+=W[uiv[j]];
          }
        }
        */
        for (auto j : bt) {
          tmpv += V[uiv[j]];
          tmpw += W[uiv[j]];
        }
        if (tmpw <= L[loop]) {
          maxval = max(data[uidx][L[loop] - tmpw] + tmpv, maxval);
        }
      }

      cout << maxval << endl;
    }
  }

  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
#define REP(i, n) for (ll i = 0; i < n; i++)
#define ll long long
#define MOD 1000000007LL
#define llMAX 9223372036854775807LL
#define llMIN -9223372036854775808LL
using vi = vector<ll>;  // llの1次元の型に vi という別名をつける
using vvi = vector<vi>; // llの2次元の型に vvi という別名をつける

ll n;
ll M = 1e5 + 1;

// bit全探索
vi bt;
void setbit(ll i) {
  bt.clear();
  for (ll tmp = 0; i > 0; i /= 2) {
    if (i % 2 == 1)
      bt.push_back(tmp);
    tmp++;
  }
}

int main() {
  ll ans = 0, q;
  cin >> n;
  n++;
  ll nlg = ceil(log2(n));
  vi V(n), W(n);
  REP(i, n - 1) cin >> V[i + 1] >> W[i + 1];

  cin >> q;
  vi u(q), L(q);
  REP(i, q) cin >> u[i] >> L[i];

  // 上半分
  ll nhi = nlg - (nlg / 2);
  if (nhi == 9)
    nhi = 11;
  vvi data(1LL << nhi, vi(M)); // N * M の2次元配列

  for (ll i = 1; i < (1LL << nhi); i++) {
    for (ll j = 0; j < M; j++) {
      if ((j - W[i]) >= 0) {
        data[i][j] = max(data[i / 2][j - W[i]] + V[i], data[i / 2][j]);
      } else {
        data[i][j] = data[i / 2][j];
      }
    }
  }

  ll uiv[10];
  ll wuiv = 0;

  // 下半分
  for (ll loop = 0; loop < q; loop++) {
    ll uidx = u[loop];
    if (uidx < (1LL << nhi)) {
      cout << data[uidx][L[loop]] << endl;
    } else { // 上＋下
      ll maxval = 0;
      // vi uiv;
      ll nn = 0;
      wuiv = 0;
      for (;; uidx /= 2) {
        if (uidx < (1LL << nhi))
          break;
        uiv[wuiv] = uidx;
        wuiv++;
        nn++;
      }

      ll bn = 1 << nn;
      for (ll i = 0; i < bn; i++) {
        setbit(i);
        ll tmpw = 0;
        ll tmpv = 0;
        /*
        for(ll j=0;j<nn;j++){
          if (i&(1<<j)){
            tmpv+=V[uiv[j]];
            tmpw+=W[uiv[j]];
          }
        }
        */
        for (auto j : bt) {
          tmpv += V[uiv[j]];
          tmpw += W[uiv[j]];
        }
        if (tmpw <= L[loop]) {
          maxval = max(data[uidx][L[loop] - tmpw] + tmpv, maxval);
        }
      }

      cout << maxval << endl;
    }
  }

  return 0;
}