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

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

#define for_(i, a, b) for (int i = a; i < b; ++i)
#define ALL(a) a.begin(), a.end()
#define INIT(a, b) memset(a, b, sizeof(a))
using lint = long long int;

template <typename T> void maxUpdate(T &a, T b) { a = max(a, b); }

int N, Q, V[300005], W[300005], dp[20][100005];

vector<int> ch[300005];
vector<int> L[300005];
vector<int> q[300005];
vector<int> ans[300005];

const int DEP = 9;
const int MAX_L = 100000;

int solve(vector<int> &tar, int C) {
  int n = tar.size();

  function<int(int, int, int)> rec = [&](int i, int sum_v, int sum_w) {
    if (i == n)
      return sum_v + dp[DEP][C - sum_w];
    int ret = 0, v = tar[i];
    ret = max(ret, rec(i + 1, sum_v, sum_w));
    if (sum_w + W[v] <= C) {
      ret = max(ret, rec(i + 1, sum_v + V[v], sum_w + W[v]));
    }
    return ret;
  };

  return rec(0, 0, 0);
}

void dfs(int v, int d, vector<int> &tar) {
  if (d >= DEP) {
    tar.push_back(v);
  } else {
    INIT(dp[d + 1], 0);
    for_(x, 0, MAX_L + 1) {
      maxUpdate(dp[d + 1][x], dp[d][x]);
      if (x > 0)
        maxUpdate(dp[d + 1][x], dp[d + 1][x - 1]);
      int nx = x - W[v];
      if (nx >= 0)
        maxUpdate(dp[d + 1][x], dp[d][nx] + V[v]);
    }
  }

  int K = L[v].size();
  for_(i, 0, K) {
    int C = L[v][i];
    if (d < DEP)
      ans[v].push_back(dp[d + 1][C]);
    else
      ans[v].push_back(solve(tar, C));
  }

  for (int u : ch[v])
    dfs(u, d + 1, tar);

  if (d >= DEP) {
    tar.pop_back();
  }
}

int main() {
  cin >> N;
  for_(i, 1, N) {
    int p = (i - 1) / 2;
    ch[p].push_back(i);
  }
  for_(i, 0, N) cin >> V[i] >> W[i];

  cin >> Q;
  for_(i, 0, Q) {
    int vi, Li;
    cin >> vi >> Li;
    --vi;
    L[vi].push_back(Li);
    q[vi].push_back(i);
  }

  INIT(dp, 0);
  vector<int> tar;
  dfs(0, 0, tar);

  vector<int> out(Q);
  for_(v, 0, N) {
    int K = L[v].size();
    for_(k, 0, K) {
      int i = q[v][k];
      out[i] = ans[v][k];
    }
  }

  for (int o : out)
    cout << o << endl;
}

Error: TLE

Fixed submission:

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

#define for_(i, a, b) for (int i = a; i < b; ++i)
#define ALL(a) a.begin(), a.end()
#define INIT(a, b) memset(a, b, sizeof(a))
using lint = long long int;

int N, Q, val[300005], w[300005];
vector<int> ch[300005];
vector<int> Ls[300005];
vector<int> Qi[300005];
vector<int> ans[300005];

using pii = pair<int, int>;

vector<pii> enumeration(vector<int> &tar) {
  vector<pii> P;
  int n = tar.size();

  function<void(int, int, int)> rec = [&](int i, int sum_w, int sum_v) {
    if (i == n) {
      P.push_back({sum_w, sum_v});
      return;
    }
    rec(i + 1, sum_w, sum_v);
    rec(i + 1, sum_w + w[tar[i]], sum_v + val[tar[i]]);
  };
  rec(0, 0, 0);

  sort(ALL(P));
  P.push_back(pii(-1, -1));

  int mx = 0;
  vector<pii> ret;
  for_(i, 0, 1 << n) {
    mx = max(mx, P[i].second);
    if (P[i].first != P[i + 1].first)
      ret.push_back(pii(P[i].first, mx));
  }
  return ret;
}

int solve(vector<int> &tar, int C) {
  int m = tar.size();
  vector<int> A, B;
  for_(i, 0, m / 2) A.push_back(tar[i]);
  for_(i, m / 2, m) B.push_back(tar[i]);

  vector<pii> va = enumeration(A);
  vector<pii> vb = enumeration(B);
  reverse(ALL(vb));

  int i = 0, n = vb.size(), ret = 0;
  for (pii p : va) {
    while (i < n and p.first + vb[i].first > C)
      ++i;
    if (i < n)
      ret = max(ret, p.second + vb[i].second);
  }
  return ret;
}

void dfs(int v, vector<int> &tar) {
  tar.push_back(v);

  int K = Ls[v].size();
  for_(k, 0, K) {
    int C = Ls[v][k];
    ans[v].push_back(solve(tar, C));
  }

  for (int u : ch[v])
    dfs(u, tar);

  tar.pop_back();
}

int main() {
  cin >> N;
  for_(i, 1, N) {
    int p = (i - 1) / 2;
    ch[p].push_back(i);
  }
  for_(i, 0, N) cin >> val[i] >> w[i];

  cin >> Q;
  for_(i, 0, Q) {
    int v, L;
    cin >> v >> L;
    --v;
    Ls[v].push_back(L);
    Qi[v].push_back(i);
  }

  vector<int> tar;
  dfs(0, tar);

  vector<int> out(Q);
  for_(v, 0, N) {
    int K = Ls[v].size();
    for_(k, 0, K) {
      int i = Qi[v][k];
      out[i] = ans[v][k];
    }
  }

  for (int o : out)
    cout << o << endl;
}