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

#include <bits/stdc++.h>

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

using ll = long long;

template <class T, class U> void amax(T &x, U y) {
  if (x < y)
    x = y;
}

int main() {

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

  constexpr int L_MAX = 100000;

  int N;
  cin >> N;
  vector<int> V(N), W(N);
  FOR(i, 1, N + 1) cin >> V[i] >> W[i];

  int N_upper = min((1 << 9) - 1, N);
  vector<vector<ll>> dp(N_upper + 1, vector<ll>(L_MAX + 1));
  FOR(i, 1, N_upper + 1) {
    FOR(j, 1, L_MAX + 1) {
      dp[i][j] = dp[i / 2][j];
      if (j >= W[i]) {
        amax(dp[i][j], dp[i / 2][j - W[i]] + V[i]);
      }
    }
  }

  int Q;
  cin >> Q;
  REP(_, Q) {
    int v, L;
    cin >> v >> L;

    vector<int> lowers;
    while (v > N_upper) {
      lowers.push_back(v);
      v /= 2;
    }
    int H = lowers.size();
    ll result = 0;
    REP(bit, 1 << H) {
      ll sum_V = 0;
      ll sum_W = 0;
      REP(i, H) {
        if (bit & (1 << i)) {
          sum_V += V[lowers[i]];
          sum_W += W[lowers[i]];
        }
      }
      if (sum_W <= L) {
        amax(result, sum_V + dp[v][L - sum_W]);
      }
    }
    cout << result << '\\n';
  }
  cout << flush;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

using ull = unsigned long long;

// First element is weight, second element is value.
using Item = std::pair<ull, ull>;

// Helper function.
template <class ItemIterator>
std::vector<Item> _knapsack_bitdp(ItemIterator first, ItemIterator last,
                                  ull capacity) {
  int n = distance(first, last);
  std::vector<Item> a;
  for (int b = 0; b < (1 << n); ++b) {
    ull sum_value = 0;
    ull sum_weight = 0;
    for (int i = 0; i < n; ++i) {
      if (b & (1 << i)) {
        sum_weight += (*(first + i)).first;
        sum_value += (*(first + i)).second;
      }
    }
    if (sum_weight <= capacity) {
      a.push_back(Item(sum_weight, sum_value));
    }
  }
  return a;
}

// Time complexity is O(m * log(m)),
// auxiliary space is O(m * log(m)),
// where n = items.size(),
//       m = pow(2, n / 2).
ull knapsack_01_small_items(const std::vector<Item> &items, ull capacity) {
  int n = items.size();
  std::vector<Item> a1 =
      _knapsack_bitdp(items.begin(), items.begin() + n / 2, capacity);
  std::vector<Item> a2 =
      _knapsack_bitdp(items.begin() + n / 2, items.end(), capacity);
  sort(a2.begin(), a2.end());

  std::vector<ull> acc_max_value(a2.size() + 1);
  acc_max_value[0] = 0;
  for (int i = 0; i < a2.size(); ++i) {
    acc_max_value[i + 1] = std::max(acc_max_value[i], a2[i].second);
  }

  ull result = 0;
  for (const Item &item : a1) {
    ull weight1 = item.first;
    ull value1 = item.second;
    ull value2 = acc_max_value[distance(
        a2.begin(), upper_bound(a2.begin(), a2.end(),
                                Item(capacity - weight1, ULLONG_MAX)))];
    result = std::max(result, value1 + value2);
  }
  return result;
}

int main() {

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

  int N;
  cin >> N;
  vector<ull> V(N + 1), W(N + 1);
  FOR(i, 1, N + 1) cin >> V[i] >> W[i];
  int Q;
  cin >> Q;
  REP(i, Q) {
    int v, L;
    cin >> v >> L;
    vector<Item> items;
    while (v) {
      items.emplace_back(W[v], V[v]);
      v >>= 1;
    }
    cout << knapsack_01_small_items(items, L) << '\\n';
  }
  cout << flush;

  return 0;
}