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

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

#define forn(i, n) for (int i = 0; i < (int)(n); i++)
#define si(c) ((int)(c).size())
#define forsn(i, s, n) for (int i = (int)(s); i < ((int)n); i++)
#define dforsn(i, s, n) for (int i = (int)(n)-1; i >= ((int)s); i--)
#define all(c) (c).begin(), (c).end()
#define D(a) cerr << #a << "=" << a << endl;
#define pb push_back
#define eb emplace_back
#define mp make_pair

typedef long long int ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = (1 << 18) + 10;

int n, v[N], w[N], pre[N];
vector<pii> dp[N];

void clean(vector<pii> &dp) {
  sort(all(dp));
  int mx = -1;
  vector<pii> ndp;
  int i = 0;
  while (i < si(dp)) {
    while (i + 1 < si(dp) && dp[i].first == dp[i + 1].first)
      ++i;
    if (dp[i].second > mx) {
      mx = dp[i].second;
      ndp.pb(dp[i]);
    }
    ++i;
  }
  dp = ndp;
}

int query(const vector<pii> &a, const vector<pii> &b, int L) {
  int n = si(a), m = si(b);
  int j = m - 1, ans = 0;
  forn(i, n) {
    while (j >= 0 && a[i].first + b[j].first > L)
      --j;
    if (j < 0)
      break;
    ans = max(ans, a[i].second + b[j].second);
  }
  return ans;
}

vector<pii> merge(const vector<pii> &a, const vector<pii> &b) {
  vector<pii> ans;
  ans.reserve(si(a) + si(b));
  int n = si(a), m = si(b), mx = -1;
  int i = 0, j = 0;
  while (i < n && j < m) {
    if (a[i].first < b[j].first ||
        (a[i].first == b[j].first && a[i].second >= b[j].second)) {
      if (a[i].second > mx) {
        ans.pb(a[i]);
        mx = a[i].second;
      }
      i++;
    } else {
      if (b[j].second > mx) {
        ans.pb(b[j]);
        mx = b[j].second;
      }
      j++;
    }
  }
  while (i < n) {
    if (a[i].second > mx) {
      ans.pb(a[i]);
      mx = a[i].second;
    }
    i++;
  }
  while (j < m) {
    if (b[j].second > mx) {
      ans.pb(b[j]);
      mx = b[j].second;
    }
    j++;
  }
  return ans;
}

void compute_dp(int i) {
  if (!dp[i].empty())
    return;

  vi nodes;
  int u, lvl;
  for (u = i, lvl = 0; u != 0 && lvl < 9; u = u / 2, lvl++) {
    nodes.pb(u);
  }
  pre[i] = u;

  int sz = 1;
  dp[i].eb(0, 0);
  for (auto j : nodes) {
    vector<pii> ndp(sz);
    forn(k, sz) ndp[k] = {dp[i][k].first + w[j], dp[i][k].second + v[j]};
    dp[i] = merge(dp[i], ndp);
    sz = si(dp[i]);
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);

  cin >> n;
  dp[0].eb(0, 0);
  for (int i = 1; i <= n; i++)
    cin >> v[i] >> w[i];

  int q;
  cin >> q;
  while (q--) {
    int v, L;
    cin >> v >> L;
    compute_dp(v);
    compute_dp(pre[v]);
    cout << query(dp[v], dp[pre[v]], L) << '\\n';
  }

  return 0;
}


Error: TLE

Fixed submission:

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

#define forn(i, n) for (int i = 0; i < (int)(n); i++)
#define si(c) ((int)(c).size())
#define forsn(i, s, n) for (int i = (int)(s); i < ((int)n); i++)
#define dforsn(i, s, n) for (int i = (int)(n)-1; i >= ((int)s); i--)
#define all(c) (c).begin(), (c).end()
#define D(a) cerr << #a << "=" << a << endl;
#define pb push_back
#define eb emplace_back
#define mp make_pair

typedef long long int ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = (1 << 18) + 10;

int n, v[N], w[N], pre[N];
vector<pii> dp[N];

void clean(vector<pii> &dp) {
  sort(all(dp));
  int mx = -1;
  vector<pii> ndp;
  int i = 0;
  while (i < si(dp)) {
    while (i + 1 < si(dp) && dp[i].first == dp[i + 1].first)
      ++i;
    if (dp[i].second > mx) {
      mx = dp[i].second;
      ndp.pb(dp[i]);
    }
    ++i;
  }
  dp = ndp;
}

int query(const vector<pii> &a, const vector<pii> &b, int L) {
  int n = si(a), m = si(b);
  int j = m - 1, ans = 0;
  forn(i, n) {
    while (j >= 0 && a[i].first + b[j].first > L)
      --j;
    if (j < 0)
      break;
    ans = max(ans, a[i].second + b[j].second);
  }
  return ans;
}

vector<pii> merge(const vector<pii> &a, const vector<pii> &b) {
  vector<pii> ans;
  ans.reserve(si(a) + si(b));
  int n = si(a), m = si(b), mx = -1;
  int i = 0, j = 0;
  while (i < n && j < m) {
    if (a[i].first < b[j].first ||
        (a[i].first == b[j].first && a[i].second >= b[j].second)) {
      if (a[i].second > mx) {
        ans.pb(a[i]);
        mx = a[i].second;
      }
      i++;
    } else {
      if (b[j].second > mx) {
        ans.pb(b[j]);
        mx = b[j].second;
      }
      j++;
    }
  }
  while (i < n) {
    if (a[i].second > mx) {
      ans.pb(a[i]);
      mx = a[i].second;
    }
    i++;
  }
  while (j < m) {
    if (b[j].second > mx) {
      ans.pb(b[j]);
      mx = b[j].second;
    }
    j++;
  }
  return ans;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);

  cin >> n;
  dp[0].eb(0, 0);
  for (int i = 1; i <= n; i++) {
    cin >> v[i] >> w[i];

    vi nodes;
    int u, lvl;
    for (u = i, lvl = 0; u != 0 && lvl < 9; u = u / 2, lvl++) {
      nodes.pb(u);
    }
    pre[i] = u;

    int sz = 1;
    dp[i].eb(0, 0);
    for (auto j : nodes) {
      vector<pii> ndp(sz);
      forn(k, sz) ndp[k] = {dp[i][k].first + w[j], dp[i][k].second + v[j]};
      dp[i] = merge(dp[i], ndp);
      sz = si(dp[i]);
    }
    // for (auto xy : dp[i]) cerr << xy.first << ' ' << xy.second << endl;
  }

  int q;
  cin >> q;
  while (q--) {
    int v, L;
    cin >> v >> L;
    cout << query(dp[v], dp[pre[v]], L) << '\\n';
  }

  return 0;
}