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

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

const int MAXA = 100001;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);

  int n;
  cin >> n;
  vector<int> cost(n), w(n);
  for (int i = 0; i < n; i++) {
    cin >> cost[i] >> w[i];
  }

  int m = min((1 << 9) - 1, n);
  vector<vector<int>> dp(m + 1, vector<int>(MAXA, 0));
  for (int i = 1; i <= m; i++) {
    for (int j = 1; j < MAXA; j++) {
      dp[i][j] = dp[i / 2][j];
      if (j >= w[i - 1]) {
        dp[i][j] = max(dp[i][j], dp[i / 2][j - w[i - 1]] + cost[i - 1]);
      }
    }
  }

  int q;
  cin >> q;
  while (q--) {
    int v, L;
    cin >> v >> L;

    vector<int> lowers;
    while (v > m) {
      lowers.push_back(v - 1);
      v /= 2;
    }

    int ans = 0;
    for (int mask = 0; mask < (1 << lowers.size()); mask++) {
      int tot_cost = 0, tot_w = 0;
      for (int i = 0; i < lowers.size(); i++) {
        if ((mask >> i) & 1) {
          tot_cost += cost[lowers[i]];
          tot_w += w[lowers[i]];
        }
      }
      if (tot_w <= L) {
        ans = max(ans, tot_cost + dp[v][L - tot_w]);
      }
    }

    cout << ans << '\\n';
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

struct query {
  int num, L;

  query(int num = -1, int L = -1) : num(num), L(L) {}
};

const int MAXA = 100001;
const int BUBEN = 8;

int n;
vector<int> cost, w, dep, ans;
vector<vector<int>> dp, pref;
vector<vector<pair<int, int>>> dp_mask;
vector<vector<query>> queries;

void dfs(int v) {
  if (v >= n) {
    return;
  }
  dep[v] = (v ? dep[(v - 1) / 2] + 1 : 0);
  if (dep[v] < BUBEN) {
    dp[v].reserve(MAXA);
    dp[v] = (v ? dp[(v - 1) / 2] : vector<int>(MAXA, 0));
    if (v && v % 2 == 0) {
      dp[(v - 1) / 2].clear();
    }
    dp[v][w[v]] = max(dp[v][w[v]], cost[v]);
    for (int i = w[v]; i < MAXA && v; i++) {
      dp[v][i] = max(dp[v][i], dp[(v - 1) / 2][i - w[v]] + cost[v]);
    }
    if (queries[v].size()) {
      pref[v].reserve(MAXA);
      pref[v].resize(dp[v].size(), dp[v][0]);
      for (int i = 1; i < dp[v].size(); i++) {
        pref[v][i] = max(pref[v][i - 1], dp[v][i]);
      }
      for (auto &[num, L] : queries[v]) {
        ans[num] = pref[v][L];
      }
    }
  } else if (dep[v] == BUBEN) {
    dp[v].reserve(2);
    dp_mask[v].resize(2, {0, 0});
    dp_mask[v][1] = {cost[v], w[v]};
  } else {
    dp[v].reserve(1 << 9);
    dp_mask[v] = dp_mask[(v - 1) / 2];
    for (int mask = (1 << dep[v] - BUBEN); mask < (1 << dep[v] - BUBEN + 1);
         mask++) {
      dp_mask[v].push_back(dp_mask[v][mask - (1 << 31 - __builtin_clz(mask))]);
    }
    if (v % 2 == 0) {
      dp_mask[(v - 1) / 2].clear();
    }
    for (int mask = 0; mask < (1 << dep[v] - BUBEN); mask++) {
      dp_mask[v][mask + (1 << dep[v] - 9)] = {
          dp_mask[(v - 1) / 2][mask].first + cost[v],
          dp_mask[(v - 1) / 2][mask].second + w[v]};
    }
    int start = v;
    while (dep[start] >= BUBEN) {
      start = (start - 1) / 2;
    }
    for (auto &[num, L] : queries[v]) {
      for (int mask = 0; mask < (1 << dep[v] - 9); mask++) {
        auto [tot_cost, tot_w] = dp_mask[v][mask];
        ans[num] = max(ans[num], (tot_w <= L) *
                                     (tot_cost + dp[start][max(0, L - tot_w)]));
      }
    }
  }
  pref[v].clear();
  dfs(2 * v + 1);
  dfs(2 * v + 2);
  dp[v].clear();
  dp_mask[v].clear();
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  cin >> n;
  cost.resize(n);
  w.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> cost[i] >> w[i];
  }
  int q;
  cin >> q;
  ans.resize(q);
  queries.resize(n);
  for (int i = 0; i < q; i++) {
    int v, L;
    cin >> v >> L;
    queries[v - 1].push_back(query(i, L));
  }
  dep.resize(n);
  dp.resize(n);
  pref.resize(n);
  dp_mask.resize(n);
  dfs(0);
  for (auto el : ans) {
    cout << el << '\\n';
  }
}