Problem p02648 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;
constexpr int MAX_W = 100000;
constexpr int MAX_D = 9;

template <typename T>
vector<vector<T>> Make2DVector(int d1, int d2, T default_value) {
  return vector<vector<T>>(d1, vector<T>(d2, default_value));
}

template <class T> inline bool UpdateMin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T> inline bool UpdateMax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}

vector<pair<int64, int64>>
Normalize(const vector<pair<int64, int64>> &input_pairs) {
  vector<pair<int64, int64>> pairs = input_pairs;
  sort(pairs.begin(), pairs.end());

  vector<pair<int64, int64>> output_pairs;
  for (const auto &pair : pairs) {
    if (output_pairs.empty()) {
      output_pairs.push_back(pair);
    } else if (output_pairs.back().first == pair.first) {
      output_pairs.pop_back();
      output_pairs.push_back(pair);
    } else if (output_pairs.back().second < pair.second) {
      output_pairs.push_back(pair);
    }
  }
  return output_pairs;
}

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

  int n;
  cin >> n;
  vector<int64> vs(n + 1);
  vector<int64> ws(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> vs[i] >> ws[i];
  }
  int q_count;
  cin >> q_count;
  vector<int> q_nodes(q_count);
  vector<int64> q_weights(q_count);
  for (int i = 0; i < q_count; i++) {
    cin >> q_nodes[i] >> q_weights[i];
  }

  vector<vector<pair<int64, int64>>> dp(1 << MAX_D);
  dp[1] = {{0, 0}, {ws[1], vs[1]}};
  for (int v = 2; v <= min(n, (1 << MAX_D) - 1); v++) {
    int p = v / 2;
    vector<pair<int64, int64>> pairs;
    for (const auto &input_pair : dp[p]) {
      pairs.push_back(input_pair);
      if (input_pair.first + ws[v] < +MAX_W) {
        pairs.push_back({input_pair.first + ws[v], input_pair.second + vs[v]});
      }
    }
    dp[v] = Normalize(pairs);
  }

  for (int q_index = 0; q_index < q_count; q_index++) {
    int64 ans = [&]() -> int64 {
      int node = q_nodes[q_index];
      if (q_nodes[q_index] < (1 << MAX_D)) {
        int64 r = 0;
        for (const auto &pair : dp[node]) {
          if (pair.first <= q_weights[q_index]) {
            UpdateMax(r, pair.second);
          }
        }
        return r;
      }

      vector<int64> extra_vs;
      vector<int64> extra_ws;
      while (node >= (1 << MAX_D)) {
        extra_vs.push_back(vs[node]);
        extra_ws.push_back(ws[node]);
        node /= 2;
      }

      auto pairs_1 = dp[node];

      int k = extra_vs.size();
      vector<pair<int64, int64>> pairs_2;
      for (int bits = 0; bits < 1 << k; bits++) {
        int64 extra_v = 0;
        int64 extra_w = 0;
        for (int b = 0; b < k; b++) {
          if (bits & (1 << b)) {
            extra_v += extra_vs[b];
            extra_w += extra_ws[b];
          }
        }
        if (extra_w > q_weights[q_index])
          continue;
        pairs_2.push_back({extra_w, extra_v});
      }
      pairs_2 = Normalize(pairs_2);

      int64 r = 0;
      int cursor = pairs_2.size() - 1;
      for (int i = 0; i < pairs_1.size(); i++) {
        if (pairs_1[i].first > q_weights[q_index])
          break;
        while (pairs_1[i].first + pairs_2[cursor].first > q_weights[q_index]) {
          cursor--;
        }
        UpdateMax(r, pairs_1[i].second + pairs_2[cursor].second);
      }
      return r;
    }();
    cout << ans << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

constexpr int DEBUG = 0;
constexpr int MAX_W = 100000;
constexpr int MAX_D = 12;

template <typename T>
vector<vector<T>> Make2DVector(int d1, int d2, T default_value) {
  return vector<vector<T>>(d1, vector<T>(d2, default_value));
}

template <class T> inline bool UpdateMin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T> inline bool UpdateMax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}

vector<pair<int64, int64>>
Normalize(const vector<pair<int64, int64>> &input_pairs) {
  vector<pair<int64, int64>> pairs = input_pairs;
  sort(pairs.begin(), pairs.end());

  vector<pair<int64, int64>> output_pairs;
  for (const auto &pair : pairs) {
    if (output_pairs.empty()) {
      output_pairs.push_back(pair);
    } else if (output_pairs.back().first == pair.first) {
      output_pairs.pop_back();
      output_pairs.push_back(pair);
    } else if (output_pairs.back().second < pair.second) {
      output_pairs.push_back(pair);
    }
  }
  return output_pairs;
}

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

  int n;
  cin >> n;
  vector<int64> vs(n + 1);
  vector<int64> ws(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> vs[i] >> ws[i];
  }
  int q_count;
  cin >> q_count;
  vector<int> q_nodes(q_count);
  vector<int64> q_weights(q_count);
  for (int i = 0; i < q_count; i++) {
    cin >> q_nodes[i] >> q_weights[i];
  }

  vector<vector<pair<int64, int64>>> dp(1 << MAX_D);
  dp[1] = {{0, 0}, {ws[1], vs[1]}};
  for (int v = 2; v <= min(n, (1 << MAX_D) - 1); v++) {
    int p = v / 2;
    vector<pair<int64, int64>> pairs;
    for (const auto &input_pair : dp[p]) {
      pairs.push_back(input_pair);
      if (input_pair.first + ws[v] < +MAX_W) {
        pairs.push_back({input_pair.first + ws[v], input_pair.second + vs[v]});
      }
    }
    dp[v] = Normalize(pairs);
  }

  for (int q_index = 0; q_index < q_count; q_index++) {
    int64 ans = [&]() -> int64 {
      int node = q_nodes[q_index];
      if (q_nodes[q_index] < (1 << MAX_D)) {
        int64 r = 0;
        for (const auto &pair : dp[node]) {
          if (pair.first <= q_weights[q_index]) {
            UpdateMax(r, pair.second);
          }
        }
        return r;
      }

      vector<int64> extra_vs;
      vector<int64> extra_ws;
      while (node >= (1 << MAX_D)) {
        extra_vs.push_back(vs[node]);
        extra_ws.push_back(ws[node]);
        node /= 2;
      }

      auto pairs_1 = dp[node];

      int k = extra_vs.size();
      vector<pair<int64, int64>> pairs_2;
      for (int bits = 0; bits < 1 << k; bits++) {
        int64 extra_v = 0;
        int64 extra_w = 0;
        for (int b = 0; b < k; b++) {
          if (bits & (1 << b)) {
            extra_v += extra_vs[b];
            extra_w += extra_ws[b];
          }
        }
        if (extra_w > q_weights[q_index])
          continue;
        pairs_2.push_back({extra_w, extra_v});
      }
      pairs_2 = Normalize(pairs_2);

      int64 r = 0;
      int cursor = pairs_2.size() - 1;
      for (int i = 0; i < pairs_1.size(); i++) {
        if (pairs_1[i].first > q_weights[q_index])
          break;
        while (pairs_1[i].first + pairs_2[cursor].first > q_weights[q_index]) {
          cursor--;
        }
        UpdateMax(r, pairs_1[i].second + pairs_2[cursor].second);
      }
      return r;
    }();
    cout << ans << endl;
  }
}