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

#include <algorithm>
#include <array>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << '{';
  string sep;
  for (const auto &x : v)
    os << sep << x, sep = ", ";
  return os << '}';
}
template <typename T, size_t size>
ostream &operator<<(ostream &os, const array<T, size> &arr) {
  os << '{';
  string sep;
  for (const auto &x : arr)
    os << sep << x, sep = ", ";
  return os << '}';
}
template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}

void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) {
  cerr << ' ' << H;
  dbg_out(T...);
}

#ifdef NEAL_DEBUG
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif

const int INF = 1e9 + 5;

int N, H, K, Q;
vector<int> V, W;
vector<vector<array<int, 2>>> options;

int level(int x) { return 31 - __builtin_clz(x); }

vector<array<int, 2>> generate_options(vector<int> v, vector<int> w) {
  assert(v.size() == w.size());
  int n = int(v.size());
  vector<array<int, 2>> opts(1 << n, {0, 0});
  vector<array<int, 2>> buffer(1 << n);

  for (int bit = 0; bit < n; bit++) {
    for (int mask = 0; mask < 1 << bit; mask++)
      opts[(1 << bit) + mask] = {opts[mask][0] + w[bit],
                                 opts[mask][1] + v[bit]};

    merge(opts.begin(), opts.begin() + (1 << bit), opts.begin() + (1 << bit),
          opts.begin() + (2 << bit), buffer.begin());
    swap(opts, buffer);
  }

  vector<array<int, 2>> new_opts;
  int best_v = -1;

  for (auto &opt : opts)
    if (opt[1] > best_v) {
      best_v = opt[1];
      new_opts.push_back(opt);
    }

  return new_opts;
}

int query(int v, int L) {
  auto it =
      upper_bound(options[v].begin(), options[v].end(), array<int, 2>{L, INF});

  if (it == options[v].begin())
    return -INF;

  it--;
  return (*it)[1];
}

int main() {
  ios::sync_with_stdio(false);
#ifndef NEAL_DEBUG
  cin.tie(nullptr);
#endif

  cin >> N;
  H = 32 - __builtin_clz(N);
  K = max(2 * H / 3, 1);
  V.assign(N + 1, 0);
  W.assign(N + 1, 0);

  for (int i = 1; i <= N; i++)
    cin >> V[i] >> W[i];

  options.resize(N + 1);
  options[0] = {{0, 0}};

  for (int i = 1; i <= N; i++) {
    vector<int> v, w;
    int cutoff = level(i) < K ? level(i) : level(i) - K;

    for (int d = 0; d <= cutoff; d++) {
      v.push_back(V[i >> d]);
      w.push_back(W[i >> d]);
    }

    options[i] = generate_options(v, w);
  }

  cin >> Q;

  for (int q = 0; q < Q; q++) {
    int v, L;
    cin >> v >> L;
    int best = -INF;

    if (level(v) < K) {
      best = query(v, L);
    } else {
      int above = v >> (level(v) - K + 1);

      for (auto &opt : options[v])
        if (opt[0] <= L)
          best = max(best, opt[1] + query(above, L - opt[0]));
    }

    cout << best << '\\n';
  }
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << '{';
  string sep;
  for (const auto &x : v)
    os << sep << x, sep = ", ";
  return os << '}';
}
template <typename T, size_t size>
ostream &operator<<(ostream &os, const array<T, size> &arr) {
  os << '{';
  string sep;
  for (const auto &x : arr)
    os << sep << x, sep = ", ";
  return os << '}';
}
template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}

void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) {
  cerr << ' ' << H;
  dbg_out(T...);
}

#ifdef NEAL_DEBUG
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif

const int INF = 1e9 + 5;

int N, H, K, Q;
vector<int> V, W;
vector<vector<array<int, 2>>> options;

int main() {
  ios::sync_with_stdio(false);
#ifndef NEAL_DEBUG
  cin.tie(nullptr);
#endif

  cin >> N;
  H = 32 - __builtin_clz(N);
  K = (H + 1) / 2;
  V.assign(N + 1, 0);
  W.assign(N + 1, 0);

  for (int i = 1; i <= N; i++)
    cin >> V[i] >> W[i];

  options.resize(N + 1);
  options[0] = {{0, 0}};

  vector<array<int, 2>> buffer(1 << K);
  vector<array<int, 2>> opts(1 << K);

  for (int i = 1; i <= N; i++) {
    vector<int> v, w;

    for (int d = 0; d < K; d++) {
      v.push_back(V[i >> d]);
      w.push_back(W[i >> d]);
    }

    opts.assign(1 << K, {0, 0});

    for (int bit = 0; bit < K; bit++) {
      for (int mask = 0; mask < 1 << bit; mask++)
        opts[(1 << bit) + mask] = {opts[mask][0] + w[bit],
                                   opts[mask][1] + v[bit]};

      merge(opts.begin(), opts.begin() + (1 << bit), opts.begin() + (1 << bit),
            opts.begin() + (2 << bit), buffer.begin());
      swap(opts, buffer);
    }

    int optimal_count = 0;
    int best_v = -1;

    for (auto &opt : opts)
      if (opt[1] > best_v) {
        best_v = opt[1];
        optimal_count++;
      }

    options[i].resize(optimal_count);
    int index = 0;
    best_v = -1;

    for (auto &opt : opts)
      if (opt[1] > best_v) {
        best_v = opt[1];
        options[i][index++] = opt;
      }
  }

  cin >> Q;

  for (int q = 0; q < Q; q++) {
    int v, L;
    cin >> v >> L;
    int above = v >> K;
    int best = -INF;
    int above_index = int(options[above].size()) - 1;

    for (auto &opt : options[v]) {
      while (above_index >= 0 && opt[0] + options[above][above_index][0] > L)
        above_index--;

      if (above_index >= 0)
        best = max(best, opt[1] + options[above][above_index][1]);
    }

    cout << best << '\\n';
  }
}