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

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

const int M = 9;
const int N = 110000;

int V[1 << 18], W[1 << 18];
int dp[1 << M][N], sumW[N], sumV[N];

int main() {

  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);

  int n;
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> V[i] >> W[i];
  for (int i = 1; i < min(1 << M, n + 1); i++) {
    for (int j = N - 1; j >= 0; j--) {
      dp[i][j] = max(dp[i][j], dp[i / 2][j]);
      if (j + W[i] < N)
        dp[i][j + W[i]] = max(dp[i][j + W[i]], dp[i / 2][j] + V[i]);
    }
    for (int j = 1; j < N; j++)
      dp[i][j] = max(dp[i][j], dp[i][j - 1]);
  }
  int q;
  cin >> q;
  while (q--) {
    int u, L;
    cin >> u >> L;
    if (u < (1 << M))
      cout << dp[u][L] << "\\n";
    else {
      int v = u;
      vector<pair<int, int>> val;
      while (u)
        val.emplace_back(V[u], W[u]), u >>= 1;
      sumW[0] = sumV[0] = 0;
      int ans = 0;
      for (int i = 0; i < val.size() - M; i++)
        v >>= 1;
      for (int s = 0; s < (1 << val.size() - M); s++)
        sumW[s] = sumV[s] = 0;
      for (int s = 1; s < (1 << val.size() - M); s++) {
        int nn = __builtin_ctz(s);
        sumW[s] = max(sumW[s], sumW[s ^ (1 << nn)] + val[nn].second);
        sumV[s] = max(sumV[s], sumV[s ^ (1 << nn)] + val[nn].first);
        if (sumW[s] <= L)
          ans = max(ans, sumV[s] + dp[v][L - sumW[s]]);
      }
      cout << max(ans, dp[v][L]) << "\\n";
    }
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <map>
#include <memory.h>
using namespace std;

int V[270000], L[270000];
int rv[20], rl[20];

int sv[550], sl[550];
map<int, int> mp;

struct UandL {
  int v, l;
  UandL(int _v = 0, int _l = 0) { v = _v, l = _l; }
  bool operator<(const UandL &a) const {
    if (a.l != l)
      return l < a.l;
    return v > a.v;
  }
} val[550];

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i)
    scanf("%d%d", V + i, L + i);
  int q;
  scanf("%d", &q);
  while (q--) {
    int v, l, ct = 0;
    scanf("%d%d", &v, &l);
    while (v) {
      rv[ct] = V[v];
      rl[ct++] = L[v];
      v /= 2;
    }
    int limit = ct > 9 ? 9 : ct;
    memset(sv, 0, sizeof sv);
    memset(sl, 0, sizeof sl);
    for (int i = 1; i < (1 << limit); ++i) {
      int kp = i - (i & -i);
      int tp = (i & -i), ct = -1;
      while (tp)
        tp /= 2, ++ct;
      sv[i] = sv[kp] + rv[ct];
      sl[i] = sl[kp] + rl[ct];
    }
    sv[0] = 0;
    sl[0] = 0;
    for (int i = 0; i < (1 << limit); ++i)
      val[i] = UandL(sv[i], sl[i]);
    sort(val, val + (1 << limit));
    map<int, int> mp;
    mp[sl[0]] = sv[0];
    int ptemp = sv[0];
    for (int i = 1; i < (1 << limit); ++i) {
      if (val[i].v > ptemp) {
        ptemp = val[i].v;
        mp[val[i].l] = val[i].v;
      }
    }
    for (int i = limit; i < ct; ++i)
      rv[i - limit] = rv[i], rl[i - limit] = rl[i];
    limit = ct - limit;
    for (int i = 1; i < (1 << limit); ++i) {
      int kp = i - (i & -i);
      int tp = (i & -i), ct = -1;
      while (tp)
        tp /= 2, ++ct;
      sv[i] = sv[kp] + rv[ct];
      sl[i] = sl[kp] + rl[ct];
    }
    int mx = 0;
    for (int i = 0; i < (1 << limit); ++i) {
      if (sl[i] > l)
        continue;
      map<int, int>::iterator it = mp.lower_bound(l - sl[i] + 1);
      --it;
      mx = max(mx, it->second + sv[i]);
    }
    printf("%d\\n", mx);
  }
  return 0;
}