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

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

int n, q;
int val[1 << 18], weight[1 << 18];

int v[100055], L[100055];
vector<int> query[1 << 18];
vector<int> path;

int res[100055];

vector<pair<int, int>> vec;

int tot;

pair<int, int> on9[1 << 18];

int dp[1 << 9][100001];

void dfs(int v, int par = -1) {
  if (v >= n)
    return;

  path.push_back(v);

  if (path.size() > 9) {

  } else {
    if (par == -1) {
      for (int i = (int)1e5; i >= weight[v]; i--) {
        dp[v][i] = max(dp[v][i], dp[v][i - weight[v]] + val[v]);
      }
    } else {
      for (int i = (int)1e5; i >= weight[v]; i--) {
        dp[v][i] = max(dp[par][i], dp[par][i - weight[v]] + val[v]);
      }

      for (int i = (int)1e5; i >= 0; i--) {
        dp[v][i] = max(dp[par][i], dp[v][i]);
      }
    }
  }

  for (auto fuck : query[v]) {
    int l = L[fuck];

    if (path.size() <= 9) {
      res[fuck] = max(res[fuck], dp[v][l]);
      continue;
    }

    int left = (int)path.size() - 9;

    for (int mask = 0; mask < (1 << left); mask++) {
      pair<int, int> p = {0, 0};

      for (int i = 0; i < left; i++) {
        if (mask & (1 << i)) {
          p.first += weight[path[9 + i]];
          p.second += val[path[9 + i]];
        }
      }

      int need = l - p.first;

      if (need < 0)
        continue;

      res[fuck] = max(res[fuck], dp[path[8]][need] + p.second);
    }
  }

  dfs(v + v + 1, v);
  dfs(v + v + 2, v);

  path.pop_back();
}
int main() {
  cin >> n;

  for (int i = 0; i < n; i++) {
    scanf("%d %d", &val[i], &weight[i]);
  }

  cin >> q;

  for (int i = 0; i < q; i++) {
    scanf("%d %d", &v[i], &L[i]);
    //    v[i] = i + 1, L[i] = i;
    v[i]--;

    query[v[i]].push_back(i);
  }

  dfs(0);

  for (int i = 0; i < q; i++)
    printf("%d\\n", res[i]);

  return 0;
}


Error: TLE

Fixed submission:

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

int n, q;
int val[1 << 18], weight[1 << 18];

int v[100055], L[100055];
vector<int> query[1 << 18];

vector<int> path;
vector<pair<int, int>> vec[1 << 18][2];

int res[100055];

void dfs(int v, int par = -1) {
  if (v >= n)
    return;

  path.push_back(v);

  if (par >= 0) {
    vec[v][0] = vec[par][0];
    vec[v][1] = vec[par][1];
  } else {
    vec[v][0].push_back({0, 0});
    vec[v][1].push_back({0, 0});
  }

  if (path.size() <= 9) {
    int cur = (int)vec[v][0].size();

    for (int i = 0; i < cur; i++) {
      vec[v][0].push_back(
          {vec[v][0][i].first + weight[v], vec[v][0][i].second + val[v]});
    }

    sort(vec[v][0].begin(), vec[v][0].end());

    for (int i = 1; i < (int)vec[v][0].size(); i++) {
      vec[v][0][i].second = max(vec[v][0][i].second, vec[v][0][i - 1].second);
    }
  } else {
    int cur = (int)vec[v][1].size();

    for (int i = 0; i < cur; i++) {
      vec[v][1].push_back(
          {vec[v][1][i].first + weight[v], vec[v][1][i].second + val[v]});
    }
  }

  for (auto fuck : query[v]) {
    int l = L[fuck];

    if (path.size() <= 9) {
      auto ite = --lower_bound(vec[v][0].begin(), vec[v][0].end(),
                               make_pair(l + 1, -1));
      res[fuck] = max(res[fuck], ite->second);
      continue;
    }

    for (auto p : vec[v][1]) {
      int need = l - p.first;

      if (need < 0)
        continue;

      auto ite = --lower_bound(vec[v][0].begin(), vec[v][0].end(),
                               make_pair(need + 1, -1));

      res[fuck] = max(res[fuck], ite->second + p.second);
    }
  }

  dfs(v + v + 1, v);
  dfs(v + v + 2, v);

  path.pop_back();
}
int main() {
  cin >> n;

  for (int i = 0; i < n; i++) {
    scanf("%d %d", &val[i], &weight[i]);
  }

  cin >> q;

  for (int i = 0; i < q; i++) {
    scanf("%d %d", &v[i], &L[i]);
    //   v[i] = i + 1, L[i] = i;
    v[i]--;

    query[v[i]].push_back(i);
  }

  dfs(0);

  for (int i = 0; i < q; i++)
    printf("%d\\n", res[i]);

  return 0;
}