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

#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;

int b = 8;
int n;
int v[1 << 18];
int w[1 << 18];
vector<pair<int, int>> z[1 << 18];
vector<pair<int, long long>> z2[1 << 18];
vector<pair<int, long long>> z3[1 << 18];
long long ans[100000];

void dfs(int x, int d, long long sv, int sw) {
  int i;

  for (i = 0; i < z[x - 1].size(); i++) {
    int l = z[x - 1][i].first;
    int p = z[x - 1][i].second;

    if (sw <= l)
      ans[p] = max(ans[p], sv);
    if (sw + w[x - 1] <= l)
      ans[p] = max(ans[p], sv + v[x - 1]);
  }

  if (d == b) {
    z2[x - 1].push_back(make_pair(sw, sv));
    z2[x - 1].push_back(make_pair(sw + w[x - 1], sv + v[x - 1]));
    return;
  }

  if (x * 2 <= n) {
    dfs(x * 2, d + 1, sv, sw);

    if (sw + w[x - 1] <= 100000)
      dfs(x * 2, d + 1, sv + v[x - 1], sw + w[x - 1]);
  }

  if (x * 2 + 1 <= n) {
    dfs(x * 2 + 1, d + 1, sv, sw);

    if (sw + w[x - 1] <= 100000)
      dfs(x * 2 + 1, d + 1, sv + v[x - 1], sw + w[x - 1]);
  }
}

void dfs2(int x, long long sv, int sw, int p) {
  if (x >= (1 << b) && x < (1 << (b + 1))) {
    pair<int, long long> pp = make_pair(sw, 1e18);
    int q = upper_bound(z3[x - 1].begin(), z3[x - 1].end(), pp) -
            z3[x - 1].begin() - 1;
    ans[p] = max(ans[p], sv + z3[x - 1][q].second);
    return;
  }

  dfs2(x / 2, sv, sw, p);
  if (sw >= w[x - 1])
    dfs2(x / 2, sv + v[x - 1], sw - w[x - 1], p);
}

int main() {
  int q, i, j;

  scanf("%d", &n);

  for (i = 0; i < n; i++)
    scanf("%d %d", &v[i], &w[i]);

  scanf("%d", &q);

  for (i = 0; i < q; i++) {
    int x, y;

    scanf("%d %d", &x, &y);

    z[x - 1].push_back(make_pair(y, i));
  }

  dfs(1, 0, 0, 0);

  for (i = (1 << b); i < (1 << (b + 1)); i++) {
    sort(z2[i - 1].begin(), z2[i - 1].end());

    for (j = 0; j < z2[i - 1].size(); j++) {
      if (z3[i - 1].size() > 0 &&
          z3[i - 1].back().second >= z2[i - 1][j].second)
        continue;
      z3[i - 1].push_back(z2[i - 1][j]);
    }
  }

  for (i = (1 << (b + 1)); i <= n; i++) {
    for (j = 0; j < z[i - 1].size(); j++) {
      dfs2(i, 0, z[i - 1][j].first, z[i - 1][j].second);
    }
  }

  for (i = 0; i < q; i++)
    printf("%lld\\n", ans[i]);

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;

int n, c = 0;
int a[1 << 18];
int v[1 << 18];
int w[1 << 18];
long long dp[19][100001];
long long ans[100000];
vector<pair<int, pair<int, pair<int, int>>>> z;

void dfs(int x) {
  if (x * 2 <= n)
    dfs(x * 2);
  if (x * 2 + 1 <= n)
    dfs(x * 2 + 1);

  a[x - 1] = c++;
}

void dfs2(int x, int d, int &p) {
  int i;

  for (i = 0; i <= 100000; i++)
    dp[d + 1][i] = dp[d][i];

  for (i = w[x - 1]; i <= 100000; i++) {
    dp[d + 1][i] = max(dp[d + 1][i], dp[d + 1][i - 1]);
    dp[d + 1][i] = max(dp[d + 1][i], dp[d][i - w[x - 1]] + v[x - 1]);
  }

  if (x * 2 <= n)
    dfs2(x * 2, d + 1, p);
  if (x * 2 + 1 <= n)
    dfs2(x * 2 + 1, d + 1, p);

  while (p < z.size() && z[p].second.second.first == x) {
    int i = z[p].second.first;
    int l = z[p].second.second.second;
    ans[i] = dp[d + 1][l];
    p++;
  }
}

int main() {
  int q, p = 0, i;

  scanf("%d", &n);

  for (i = 0; i < n; i++)
    scanf("%d %d", &v[i], &w[i]);

  dfs(1);

  scanf("%d", &q);

  for (i = 0; i < q; i++) {
    int x, y;

    scanf("%d %d", &x, &y);

    z.push_back(make_pair(a[x - 1], make_pair(i, make_pair(x, y))));
  }

  sort(z.begin(), z.end());

  dfs2(1, 0, p);

  for (i = 0; i < q; i++)
    printf("%lld\\n", ans[i]);

  return 0;
}