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

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

int main() {
  using item = pair<int, int>;
  constexpr int Wmax = 100'000;
  constexpr int Dmax = 18;
  constexpr int Dhalf = 11;

  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int N;
  cin >> N;

  vector<item> data(N + 1);
  for (int v = 1; v <= N; v++) {
    cin >> data.at(v).first >> data.at(v).second;
  }

  // auto trimming= [](vector<int> *output){
  //   int val_cummax= -1;
  //   for(size_t w=0; w< output->size(); w++){
  //     val_cummax= max(val_cummax, output->at(w));
  //     output->at(w)= val_cummax;
  //   }
  // };

  const int Vupper = min(N + 1, 1 << Dhalf);
  vector<vector<int>> above_half(Vupper, vector<int>(Wmax + 1));
  for (int v = 1; v < Vupper; v++) {
    above_half.at(v) = above_half.at(v / 2);
    auto [val_v, wgh_v] = data.at(v);
    for (int w = Wmax; w >= wgh_v; w--) {
      above_half.at(v).at(w) = max(above_half.at(v / 2).at(w),
                                   val_v + above_half.at(v / 2).at(w - wgh_v));
    }
    // trimming(&above_half.at(v));
  }

  int Q;
  cin >> Q;

  vector<int> answers(Q);

  int v_query;
  int W_query;
  for (int q = 0; q < Q; q++) {
    cin >> v_query >> W_query;

    if (v_query < Vupper) {
      answers.at(q) = above_half.at(v_query).at(W_query);
    } else {
      int D_query = (32 - __builtin_clz(v_query)) - Dhalf;
      int v_anc = v_query >> D_query;

      int ans = 0;
      for (int tmp = 0; tmp < (1 << D_query); tmp++) {
        bitset<Dhalf> bs(tmp);

        int wgh_lower = 0;
        int val_lower = 0;
        for (int i = 0; i < D_query; i++) {
          if (bs.test(i)) {
            wgh_lower += data.at((v_query >> i)).second;
            val_lower += data.at((v_query >> i)).first;
          }
        }

        if (wgh_lower <= W_query) {
          int val_upper = above_half.at(v_anc).at(W_query - wgh_lower);

          ans = max(ans, val_upper + val_lower);
        }
      }
      answers.at(q) = ans;
    }
  }

  for (auto ans : answers) {
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

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

int main() {
  using item = pair<int, int>;
  // constexpr int Lmax = 100'000;
  constexpr int Dmax = 18;
  constexpr int Dhalf = 12;

  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int N;
  cin >> N;

  vector<item> data(N + 1);
  for (int v = 1; v <= N; v++) {
    cin >> data.at(v).first >> data.at(v).second;
  }

  auto trimming = [](map<int, int> *output) {
    queue<int> keys_erase;
    int val_cummax = -1;
    for (auto [wgh, val] : *output) {
      if (val_cummax < val) {
        val_cummax = val;
      } else {
        keys_erase.push(wgh);
      }
    }

    while (!keys_erase.empty()) {
      output->erase(keys_erase.front());
      keys_erase.pop();
    }
  };

  const int Vupper = min(N + 1, 1 << Dhalf);
  vector<map<int, int>> above_half(Vupper);
  above_half.at(0)[0] = 0;
  for (int v = 1; v < Vupper; v++) {
    above_half.at(v) = above_half.at(v / 2);
    auto [val_v, wgh_v] = data.at(v);
    for (auto [wgh, val] : above_half.at(v / 2)) {
      auto itr_prev = prev(above_half.at(v / 2).upper_bound(wgh + wgh_v));
      int val_prev = itr_prev->second;
      if (val + val_v > val_prev) {
        above_half.at(v)[wgh + wgh_v] = val + val_v;
      }
    }
    trimming(&above_half.at(v));
  }

  int Q;
  cin >> Q;

  vector<int> answers(Q);

  int v_query;
  int W_query;
  for (int q = 0; q < Q; q++) {
    cin >> v_query >> W_query;

    if (v_query < Vupper) {
      auto itr = prev(above_half.at(v_query).upper_bound(W_query));
      int ans = itr->second;

      answers.at(q) = ans;
    } else {
      int D_query = (32 - __builtin_clz(v_query)) - Dhalf;
      int v_anc = v_query >> D_query;

      int ans = 0;
      for (int tmp = 0; tmp < (1 << D_query); tmp++) {
        bitset<Dhalf> bs(tmp);

        int wgh_lower = 0;
        int val_lower = 0;
        for (int i = 0; i < D_query; i++) {
          if (bs.test(i)) {
            wgh_lower += data.at((v_query >> i)).second;
            val_lower += data.at((v_query >> i)).first;
          }
        }

        if (wgh_lower <= W_query) {
          auto itr_upper =
              prev(above_half.at(v_anc).upper_bound(W_query - wgh_lower));
          int val_upper = itr_upper->second;

          ans = max(ans, val_upper + val_lower);
        }
      }
      answers.at(q) = ans;
    }
  }

  for (auto ans : answers) {
    cout << ans << endl;
  }
}