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

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

const int N = 1e6 + 100, M = 13;

int v[N], w[N];

vector<pair<int, int>> pre[1 << M];

int main() {
  // freopen("in.txt", "r", stdin);
  ios::sync_with_stdio(0);
  cin.tie(0);

  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> v[i] >> w[i];
  }
  int till = min(1 << M, n + 1);
  pre[0].push_back({0, 0});
  for (int i = 1; i < min(n + 1, 1 << M); i++) {
    int p = i / 2;
    vector<pair<int, int>> A = pre[p], B = pre[p];
    for (int j = 0; j < B.size(); j++) {
      B[j].first += w[i];
      B[j].second += v[i];
    }
    vector<pair<int, int>> opts;
    merge(A.begin(), A.end(), B.begin(), B.end(), back_inserter(opts));
    int mx = -1;
    for (auto t : opts) {
      if (t.second <= mx)
        continue;
      mx = t.second;
      pre[i].push_back(t);
    }
  }
  int q;
  cin >> q;
  while (q--) {
    int u, L;
    cin >> u >> L;
    if (u < till) {
      int idx =
          lower_bound(pre[u].begin(), pre[u].end(), make_pair(L, (int)1e9)) -
          pre[u].begin() - 1;
      assert(idx >= 0);
      cout << pre[u][idx].second << "\\n";
    } else {
      vector<pair<int, int>> alls;
      while (u >= till) {
        alls.push_back({v[u], w[u]});
        u /= 2;
      }
      int sz = alls.size();
      int best = 0;
      for (int mask = 0; mask < (1 << sz); mask++) {
        int tot_w = 0, tot_v = 0;
        for (int k = 0; k < mask; k++) {
          if ((mask >> k) & 1) {
            tot_v += alls[k].first;
            tot_w += alls[k].second;
          }
        }
        if (tot_w > L)
          continue;
        int idx = lower_bound(pre[u].begin(), pre[u].end(),
                              make_pair(L - tot_w, (int)1e9)) -
                  pre[u].begin() - 1;
        assert(idx >= 0);
        int cur = pre[u][idx].second + tot_v;
        best = max(best, cur);
      }
      cout << best << "\\n";
    }
  }
  return 0;
}


Error: TLE

Fixed submission:

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

const int N = 1e6 + 100, M = 5000;

int v[N], w[N];

vector<pair<int, int>> pre[M];

int main() {
  // freopen("in.txt", "r", stdin);
  ios::sync_with_stdio(0);
  cin.tie(0);

  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> v[i] >> w[i];
  }
  int till = min(1 << 12, n + 1);
  for (int i = 1; i < min(n + 1, 1 << 12); i++) {
    vector<pair<int, int>> alls;
    int x = i;
    while (x) {
      alls.push_back({v[x], w[x]});
      x /= 2;
    }
    int sz = alls.size();
    vector<pair<int, int>> opts;
    for (int mask = 0; mask < (1 << sz); mask++) {
      int tot_w = 0, tot_v = 0;
      for (int k = 0; k < mask; k++) {
        if ((mask >> k) & 1) {
          tot_v += alls[k].first;
          tot_w += alls[k].second;
        }
      }
      opts.push_back({tot_w, tot_v});
    }
    sort(opts.begin(), opts.end());
    int mx = -1;
    for (auto t : opts) {
      if (t.second <= mx)
        continue;
      mx = t.second;
      pre[i].push_back(t);
    }
  }
  int q;
  cin >> q;
  while (q--) {
    int u, L;
    cin >> u >> L;
    if (u < till) {
      int idx =
          lower_bound(pre[u].begin(), pre[u].end(), make_pair(L, (int)1e9)) -
          pre[u].begin() - 1;
      assert(idx >= 0);
      cout << pre[u][idx].second << "\\n";
    } else {
      vector<pair<int, int>> alls;
      while (u >= till) {
        alls.push_back({v[u], w[u]});
        u /= 2;
      }
      int sz = alls.size();
      int best = 0;
      for (int mask = 0; mask < (1 << sz); mask++) {
        int tot_w = 0, tot_v = 0;
        for (int k = 0; k < mask; k++) {
          if ((mask >> k) & 1) {
            tot_v += alls[k].first;
            tot_w += alls[k].second;
          }
        }
        if (tot_w > L)
          continue;
        int idx = lower_bound(pre[u].begin(), pre[u].end(),
                              make_pair(L - tot_w, (int)1e9)) -
                  pre[u].begin() - 1;
        assert(idx >= 0);
        int cur = pre[u][idx].second + tot_v;
        best = max(best, cur);
      }
      cout << best << "\\n";
    }
  }
  return 0;
}