Problem p02648 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define fi first
#define se second
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define drep(i, n) for (int i = (n)-1; i >= 0; --i)
#define srep(i, s, t) for (int i = s; i < t; ++i)
#define rng(a) a.begin(), a.end()
#define sz(x) (int)(x).size()
#define uni(x) x.erase(unique(rng(x)), x.end())
#define show(x) cout << #x << " = " << x << endl;
#define PQ(T) priority_queue<T, v(T), greater<T>>
#define newline puts("")
#define v(T) vector<T>
#define vv(T) v(v(T))
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
typedef set<int> S;
typedef queue<int> Q;
typedef queue<P> QP;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<P> vp;
const ll LINF = 1001002003004005006ll;
const int INF = 1001001001;
const int MOD = 1000000007;

int N;
vi tv, tw;
int q;
vp qq;
int border;
v(vl) dp;

int depth(int k) {
  if (k == 0)
    return 1;
  return depth((k + 1) / 2 - 1) + 1;
}

int main() {
  cin >> N;
  tv.resize(N);
  tw.resize(N);
  rep(i, N) { cin >> tv[i] >> tw[i]; }
  int L = 0;
  cin >> q;
  qq.resize(q);
  rep(qi, q) {
    cin >> qq[qi].first >> qq[qi].second;
    chmax(L, qq[qi].second + 1);
  }
  const int X = 9;
  border = min(1 << (X + 1) - 1, N);
  dp.assign(border, vl(L, 0));
  rep(i, L) {
    if (i - tw[0] < 0)
      continue;
    dp[0][i] = tv[0];
  }
  srep(i, 1, border) {
    int p = (i + 1) / 2 - 1;
    dp[i] = dp[p];
    drep(j, L) {
      if (j - tw[i] < 0)
        continue;
      chmax(dp[i][j], dp[i][j - tw[i]] + tv[i]);
    }
  }

  rep(qi, q) {
    int k = depth(qq[qi].first - 1);
    if (k <= X) {
      cout << dp[qq[qi].first - 1][qq[qi].second] << endl;
      continue;
    }
    ll ans = 0;
    rep(b, 1 << (k - X)) {
      ll sw = 0, sv = 0;
      int now = qq[qi].first - 1;
      rep(i, k - X) {
        if ((b >> i) & 1) {
          sw += tw[now];
          sv += tv[now];
        }
        now = (now + 1) / 2 - 1;
      }
      if (sw > qq[qi].second)
        continue;
      int rem = qq[qi].second - sw;
      chmax(ans, sv + dp[now][rem]);
    }
    cout << ans << endl;
  }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define fi first
#define se second
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define drep(i, n) for (int i = (n)-1; i >= 0; --i)
#define srep(i, s, t) for (int i = s; i < t; ++i)
#define rng(a) a.begin(), a.end()
#define sz(x) (int)(x).size()
#define uni(x) x.erase(unique(rng(x)), x.end())
#define show(x) cout << #x << " = " << x << endl;
#define PQ(T) priority_queue<T, v(T), greater<T>>
#define newline puts("")
#define v(T) vector<T>
#define vv(T) v(v(T))
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
typedef set<int> S;
typedef queue<int> Q;
typedef queue<P> QP;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<P> vp;
const ll LINF = 1001002003004005006ll;
const int INF = 1001001001;
const int MOD = 1000000007;

int N;
vi tv, tw;
int q;
vp qq;
int border;
v(vl) dp;

int depth(int k) {
  if (k == 0)
    return 1;
  return depth((k + 1) / 2 - 1) + 1;
}

int main() {
  cin >> N;
  tv.resize(N);
  tw.resize(N);
  rep(i, N) { cin >> tv[i] >> tw[i]; }
  int L = 0;
  cin >> q;
  qq.resize(q);
  rep(qi, q) {
    cin >> qq[qi].first >> qq[qi].second;
    chmax(L, qq[qi].second + 1);
  }
  const int X = 10;
  border = min(1 << (X + 1) - 1, N);
  dp.assign(border, vl(L, 0));
  rep(i, L) {
    if (i - tw[0] < 0)
      continue;
    dp[0][i] = tv[0];
  }
  srep(i, 1, border) {
    int p = (i + 1) / 2 - 1;
    dp[i] = dp[p];
    drep(j, L) {
      if (j - tw[i] < 0)
        continue;
      chmax(dp[i][j], dp[i][j - tw[i]] + tv[i]);
    }
  }

  rep(qi, q) {
    int k = depth(qq[qi].first - 1);
    if (k <= X) {
      cout << dp[qq[qi].first - 1][qq[qi].second] << endl;
      continue;
    }
    ll ans = 0;
    rep(b, 1 << (k - X)) {
      ll sw = 0, sv = 0;
      int now = qq[qi].first - 1;
      rep(i, k - X) {
        if ((b >> i) & 1) {
          sw += tw[now];
          sv += tv[now];
        }
        now = (now + 1) / 2 - 1;
      }
      if (sw > qq[qi].second)
        continue;
      int rem = qq[qi].second - sw;
      chmax(ans, sv + dp[now][rem]);
    }
    cout << ans << endl;
  }

  return 0;
}