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

#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

struct Node {
  long long int value;
  int weight;
};
int bit_length(const int value) {
  return value == 0 ? 0 : 1 + bit_length(value >> 1);
}
int main() {
  constexpr int l_max = 100000;
  std::cin.tie(nullptr);
  std::cin.sync_with_stdio(false);
  int n;
  std::cin >> n;
  std::vector<Node> nodes(n);
  for (auto &node : nodes)
    std::cin >> node.value >> node.weight;
  std::vector<std::vector<Node>> cache(1 << (bit_length(n) >> 1));
  cache[0].push_back(Node{0, 0});
  cache[0].push_back(nodes[0]);
  for (auto i = 1; i < cache.size(); ++i) {
    const auto prev = ((i + 1) >> 1) - 1;
    cache[i] = cache[prev];
    const auto current = nodes[i];
    for (const auto &p : cache[prev]) {
      if (p.weight + current.weight > l_max)
        continue;
      cache[i].push_back(
          Node{current.value + p.value, current.weight + p.weight});
    }
  }
  const auto comparator = [](const Node &a, const Node &b) {
    return a.weight == b.weight ? a.value > b.value : a.weight < b.weight;
  };
  for (auto &s : cache) {
    std::sort(s.begin(), s.end(), comparator);
    for (auto i = 1; i < s.size(); ++i) {
      s[i].value = std::max(s[i].value, s[i - 1].value);
    }
  }
  const auto find = [](const int weight, const Node &a) {
    return a.weight > weight;
  };
  int q;
  std::vector<Node> until;
  until.reserve(n - cache.size());
  for (std::cin >> q; q > 0; --q) {
    int u, l;
    std::cin >> u >> l;
    if (u <= cache.size()) {
      const auto pos = std::distance(
          cache[u - 1].begin(),
          std::upper_bound(cache[u - 1].begin(), cache[u - 1].end(), l, find));
      if (pos > 0) {
        std::cout << cache[u - 1][pos - 1].value << '\\n';
      } else {
        std::cout << 0 << '\\n';
      }
    } else {
      until.clear();
      until.push_back(Node{0, 0});
      while (u > cache.size()) {
        const auto node = nodes[u - 1];
        for (int i = until.size() - 1; i >= 0; --i) {
          if (until[i].weight + node.weight > l)
            continue;
          until.push_back(
              Node{until[i].value + node.value, until[i].weight + node.weight});
        }
        u >>= 1;
      }
      long long int result{0};
      for (const auto &n : until) {
        const auto pos = std::distance(cache[u - 1].begin(),
                                       std::upper_bound(cache[u - 1].begin(),
                                                        cache[u - 1].end(),
                                                        l - n.weight, find));
        if (pos > 0) {
          result = std::max(result, cache[u - 1][pos - 1].value + n.value);
        }
      }
      std::cout << result << '\\n';
    }
  }
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

struct Node {
  long long int value;
  int weight;
};
int bit_length(const int value) {
  return value == 0 ? 0 : 1 + bit_length(value >> 1);
}
int main() {
  constexpr int l_max = 100000;
  std::cin.tie(nullptr);
  std::cin.sync_with_stdio(false);
  int n;
  std::cin >> n;
  std::vector<Node> nodes(n);
  for (auto &node : nodes)
    std::cin >> node.value >> node.weight;
  std::vector<std::vector<Node>> cache(1 << (bit_length(n) - 1));
  cache[0].push_back(Node{0, 0});
  cache[0].push_back(nodes[0]);
  for (auto i = 1; i < cache.size(); ++i) {
    const auto prev = ((i + 1) >> 1) - 1;
    cache[i] = cache[prev];
    const auto current = nodes[i];
    for (const auto &p : cache[prev]) {
      if (p.weight + current.weight > l_max)
        continue;
      cache[i].push_back(
          Node{current.value + p.value, current.weight + p.weight});
    }
  }
  const auto comparator = [](const Node &a, const Node &b) {
    return a.weight == b.weight ? a.value > b.value : a.weight < b.weight;
  };
  for (auto &s : cache) {
    std::sort(s.begin(), s.end(), comparator);
    for (auto i = 1; i < s.size(); ++i) {
      s[i].value = std::max(s[i].value, s[i - 1].value);
    }
  }
  const auto find = [](const int weight, const Node &a) {
    return a.weight > weight;
  };
  int q;
  std::vector<Node> until;
  until.reserve(n - cache.size());
  for (std::cin >> q; q > 0; --q) {
    int u, l;
    std::cin >> u >> l;
    if (u <= cache.size()) {
      const auto pos = std::distance(
          cache[u - 1].begin(),
          std::upper_bound(cache[u - 1].begin(), cache[u - 1].end(), l, find));
      if (pos > 0) {
        std::cout << cache[u - 1][pos - 1].value << '\\n';
      } else {
        std::cout << 0 << '\\n';
      }
    } else {
      until.clear();
      until.push_back(Node{0, 0});
      while (u > cache.size()) {
        const auto node = nodes[u - 1];
        for (int i = until.size() - 1; i >= 0; --i) {
          if (until[i].weight + node.weight > l)
            continue;
          until.push_back(
              Node{until[i].value + node.value, until[i].weight + node.weight});
        }
        u >>= 1;
      }
      long long int result{0};
      for (const auto &n : until) {
        const auto pos = std::distance(cache[u - 1].begin(),
                                       std::upper_bound(cache[u - 1].begin(),
                                                        cache[u - 1].end(),
                                                        l - n.weight, find));
        if (pos > 0) {
          result = std::max(result, cache[u - 1][pos - 1].value + n.value);
        }
      }
      std::cout << result << '\\n';
    }
  }
}