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

// clang-format off
#include <bits/stdc++.h>

#define mp make_pair
#define fst first
#define snd second
#define forn(i,n) for (int i = 0; i < int(n); i++)
#define forn1(i,n) for (int i = 1; i <= int(n); i++)
#define popcnt __builtin_popcount
#define ffs __builtin_ffs
#define ctz __builtin_ctz
#define clz __builtin_clz
#define all(a) (a).begin(), (a).end()
 
using namespace std;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pli = pair<ll,int>;
using pil = pair<int,ll>;
using pll = pair<ll,ll>;
template <typename T> using vec = vector<T>;
using vi = vec<int>;
using vl = vec<ll>;
template <typename T> using que = queue<T>;
template <typename T> using deq = deque<T>;

template <typename T> T id(T b) {return b;};
template <typename T> void chmax(T &x, T y) {if (x < y) x = y;}
template <typename T> void chmin(T &x, T y) {if (x > y) x = y;}
template <typename S, typename K> bool contains(S &s, K k) { return s.find(k) != s.end(); }
void fastio() { ios_base::sync_with_stdio(false); cin.tie(nullptr); }
constexpr ll TEN(int n) { if (n == 0) return 1LL; else return 10LL*TEN(n-1); }
// clang-format on

const int MAX_N = 1 << 18;
int n;
int v[MAX_N + 1], w[MAX_N + 1];
ll dp[1 << 10][100001];
bool vis[1 << 10][100001];

ll rec(int i, int j) {
  if (i == 0)
    return 0;
  if (vis[i][j])
    return dp[i][j];

  vis[i][j] = true;

  dp[i][j] = rec(i / 2, j);

  if (j >= w[i]) {
    chmax(dp[i][j], rec(i / 2, j - w[i]) + v[i]);
  }

  return dp[i][j];
}

int main() {
  fastio();

  cin >> n;
  forn1(i, n) { cin >> v[i] >> w[i]; }

  forn(i, min(n + 1, 1 << 10)) {
    forn(j, 100001) { rec(i, j); }
  }

  int q;
  cin >> q;
  while (q--) {
    int x, l;
    cin >> x >> l;

    if (x < (1 << 10)) {
      cout << dp[x][l] << "\\n";
      continue;
    }

    vi nodes;
    while (x >= (1 << 10)) {
      nodes.push_back(x);
      x /= 2;
    }

    ll ans = 0;
    int m = nodes.size();
    for (int b = 0; b < (1 << m); b++) {
      ll total_w = 0;
      ll total_v = 0;
      for (int i = 0; i < m; i++) {
        if ((b >> i) & 1) {
          total_w += w[nodes[i]];
          total_v += v[nodes[i]];
        }
      }

      if (total_w > l) {
        continue;
      }

      chmax(ans, total_v + dp[x][l - total_w]);
    }

    cout << ans << "\\n";
  }

  return 0;
}

Error: TLE

Fixed submission:

// clang-format off
#include <bits/stdc++.h>

#define mp make_pair
#define fst first
#define snd second
#define forn(i,n) for (int i = 0; i < int(n); i++)
#define forn1(i,n) for (int i = 1; i <= int(n); i++)
#define popcnt __builtin_popcount
#define ffs __builtin_ffs
#define ctz __builtin_ctz
#define clz __builtin_clz
#define all(a) (a).begin(), (a).end()
 
using namespace std;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pli = pair<ll,int>;
using pil = pair<int,ll>;
using pll = pair<ll,ll>;
template <typename T> using vec = vector<T>;
using vi = vec<int>;
using vl = vec<ll>;
template <typename T> using que = queue<T>;
template <typename T> using deq = deque<T>;

template <typename T> T id(T b) {return b;};
template <typename T> void chmax(T &x, T y) {if (x < y) x = y;}
template <typename T> void chmin(T &x, T y) {if (x > y) x = y;}
template <typename S, typename K> bool contains(S &s, K k) { return s.find(k) != s.end(); }
void fastio() { ios_base::sync_with_stdio(false); cin.tie(nullptr); }
constexpr ll TEN(int n) { if (n == 0) return 1LL; else return 10LL*TEN(n-1); }
// clang-format on

const int MAX_N = 1 << 18;
int n;
int v[MAX_N + 1], w[MAX_N + 1];
ll dp[1 << 9][100001];
bool vis[1 << 9][100001];

ll rec(int i, int j) {
  if (i == 0)
    return 0;
  if (vis[i][j])
    return dp[i][j];

  vis[i][j] = true;

  dp[i][j] = rec(i / 2, j);

  if (j >= w[i]) {
    chmax(dp[i][j], rec(i / 2, j - w[i]) + v[i]);
  }

  return dp[i][j];
}

int main() {
  fastio();

  cin >> n;
  forn1(i, n) { cin >> v[i] >> w[i]; }

  forn(i, min(n + 1, 1 << 9)) {
    forn(j, 100001) { rec(i, j); }
  }

  int q;
  cin >> q;
  while (q--) {
    int x, l;
    cin >> x >> l;

    if (x < (1 << 9)) {
      cout << dp[x][l] << "\\n";
      continue;
    }

    vi nodes;
    while (x >= (1 << 9)) {
      nodes.push_back(x);
      x /= 2;
    }

    ll ans = 0;
    int m = nodes.size();
    for (int b = 0; b < (1 << m); b++) {
      ll total_w = 0;
      ll total_v = 0;
      for (int i = 0; i < m; i++) {
        if ((b >> i) & 1) {
          total_w += w[nodes[i]];
          total_v += v[nodes[i]];
        }
      }

      if (total_w > l) {
        continue;
      }

      chmax(ans, total_v + dp[x][l - total_w]);
    }

    cout << ans << "\\n";
  }

  return 0;
}