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

#include <bits/stdc++.h>

using ll = int;
const int maxn = (1 << 18) + 3, maxq = 1e5 + 3, maxl = 10, maxbl = 1 << maxl;

int n, q, v[maxn], w[maxn], blp[maxn], bc[maxn];
std::pair<ll, ll> bt[maxbl], bs[maxbl];

inline int calcBt(int s, std::pair<ll, ll> *b, bool sorted) {
  int l = bc[s];
  b[0].first = b[0].second = 0;
  for (int i = 0, u = s; i < l; ++i, u /= 2) {
    b[1 << i].first = w[u];
    b[1 << i].second = v[u];
  }
  for (int i = 3; i < (1 << l); ++i) {
    auto &bu = b[i - (i & -i)], &bv = b[i & -i];
    b[i].first = bu.first + bv.first;
    b[i].second = bu.second + bv.second;
  }
  if (sorted) {
    std::sort(b, b + (1 << l));
    for (int i = 1; i < (1 << l); ++i) {
      auto &bu = b[i].second, &bv = b[i - 1].second;
      if (bu < bv)
        bu = bv;
    }
    int bl = 0;
    for (int j = 0; j < (1 << l); ++j) {
      if (bl && b[bl - 1].first == b[j].first) {
        b[bl - 1].second = std::max(b[bl - 1].second, b[j].second);
      } else {
        b[bl++] = b[j];
      }
    }
    return bl;
  }
  return 1 << l;
}

inline int lbs(ll w, int bsl) {
  int l = 0, r = bsl;
  while (r - l > 1) {
    int mid = (l + r) / 2;
    if (bs[mid].first <= w)
      l = mid;
    else
      r = mid;
  }
  return l;
}

inline ll query(int u, ll l) {
  int bsl;
  if (blp[u]) {
    bsl = calcBt(blp[u], bs, true);
  } else {
    bsl = 1;
    bs[0].first = bs[0].second = 0;
  }
  int btl = calcBt(u, bt, false);
  ll ans = 0;
  for (int i = 0; i < btl; ++i) {
    auto &bu = bt[i];
    if (bu.first > l)
      continue;
    auto it = lbs(l - bu.first, bsl);
    ans = std::max(ans, bu.second + bs[it].second);
  }
  return ans;
}

void initBlp() {
  for (int i = 1; i <= n; ++i) {
    int &p = blp[i] = i, &c = bc[i] = 0;
    for (int j = 0; j < maxl && p; ++j) {
      if (p)
        c += 1;
      p /= 2;
    }
  }
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", v + i, w + i);
  }
  initBlp();
  scanf("%d", &q);
  for (int i = 0; i < q; ++i) {
    int u, l;
    scanf("%d%d", &u, &l);
    printf("%d\\n", query(u, l));
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using ll = int;
const int maxn = (1 << 18) + 3, maxq = 1e5 + 3, maxl = 9, maxbl = 1 << maxl;

int n, q, v[maxn], w[maxn], blp[maxn], bc[maxn];
std::pair<ll, ll> bt[maxbl], bs[maxbl];

inline int calcBt(int s, std::pair<ll, ll> *b, bool sorted) {
  int l = bc[s];
  b[0].first = b[0].second = 0;
  for (int i = 0, u = s; i < l; ++i, u /= 2) {
    b[1 << i].first = w[u];
    b[1 << i].second = v[u];
  }
  for (int i = 3; i < (1 << l); ++i) {
    auto &bu = b[i - (i & -i)], &bv = b[i & -i];
    b[i].first = bu.first + bv.first;
    b[i].second = bu.second + bv.second;
  }
  if (sorted) {
    std::sort(b, b + (1 << l));
    for (int i = 1; i < (1 << l); ++i) {
      auto &bu = b[i].second, &bv = b[i - 1].second;
      if (bu < bv)
        bu = bv;
    }
    int bl = 0;
    for (int j = 0; j < (1 << l); ++j) {
      if (bl && b[bl - 1].first == b[j].first) {
        b[bl - 1].second = std::max(b[bl - 1].second, b[j].second);
      } else {
        b[bl++] = b[j];
      }
    }
    return bl;
  }
  return 1 << l;
}

inline int lbs(ll w, int bsl) {
  int l = 0, r = bsl;
  while (r - l > 1) {
    int mid = (l + r) / 2;
    if (bs[mid].first <= w)
      l = mid;
    else
      r = mid;
  }
  return l;
}

inline ll query(int u, ll l) {
  int bsl;
  if (blp[u]) {
    bsl = calcBt(blp[u], bs, true);
  } else {
    bsl = 1;
    bs[0].first = bs[0].second = 0;
  }
  int btl = calcBt(u, bt, false);
  ll ans = 0;
  for (int i = 0; i < btl; ++i) {
    auto &bu = bt[i];
    if (bu.first > l)
      continue;
    auto it = lbs(l - bu.first, bsl);
    ans = std::max(ans, bu.second + bs[it].second);
  }
  return ans;
}

inline void initBlp() {
  for (int i = 1; i <= n; ++i) {
    int &p = blp[i] = i, &c = bc[i] = 0;
    for (int j = 0; j < maxl && p; ++j) {
      if (p)
        c += 1;
      p /= 2;
    }
  }
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", v + i, w + i);
  }
  initBlp();
  scanf("%d", &q);
  for (int i = 0; i < q; ++i) {
    int u, l;
    scanf("%d%d", &u, &l);
    printf("%d\\n", query(u, l));
  }
  return 0;
}