Problem p02648 (C++)

Buggy submission (status: Time Limit Exceeded):
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstring>
#include <float.h>
#include <fstream>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>
using namespace std;
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
  using P = function<OperatorMonoid(OperatorMonoid, int)>;

  int sz;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const P p;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const P p,
                  const Monoid &M1, const OperatorMonoid OM0)
      : f(f), g(g), h(h), p(p), M1(M1), OM0(OM0) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  void propagate(int k, int len) {
    if (lazy[k] != OM0) {
      if (k < sz) {
        lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
        lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      }
      data[k] = g(data[k], p(lazy[k], len));
      lazy[k] = OM0;
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return data[k];
    } else if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      propagate(k, r - l);
      return data[k];
    } else {
      return data[k] = f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
                         update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x) {
    return update(a, b, x, 1, 0, sz);
  }

  Monoid query(int a, int b, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return M1;
    } else if (a <= l && r <= b) {
      return data[k];
    } else {
      return f(query(a, b, 2 * k + 0, l, (l + r) >> 1),
               query(a, b, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid query(int a, int b) { return query(a, b, 1, 0, sz); }

  Monoid operator[](const int &k) { return query(k, k + 1); }
};
map<int64_t, int> prime_factor(int64_t n) {
  map<int64_t, int> ret;
  for (int64_t i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      ret[i]++;
      n /= i;
    }
  }
  if (n != 1)
    ret[n] = 1;
  return ret;
}
long long MOD = 998244353;
const int MAX = 510000;
long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
template <typename T> struct BinaryIndexedTree {
  vector<T> data;

  BinaryIndexedTree(int sz) { data.assign(++sz, 0); }

  T sum(int k) {
    T ret = 0;
    for (++k; k > 0; k -= k & -k)
      ret += data[k];
    return (ret);
  }

  void add(int k, T x) {
    for (++k; k < data.size(); k += k & -k)
      data[k] += x;
  }
};
typedef pair<int, int> p;
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int maxc = 13;
  int n;
  cin >> n;
  int v[300004];
  int w[300004];
  for (int i = 1; i <= n; i++) {
    cin >> v[i] >> w[i];
  }
  map<int, int> ma[3000004]; // i番目の頂点の重さx以下のときの最大価値
  ma[1][0] = 0;
  ma[1][w[1]] = v[1];
  for (int i = 2; i <= min(n, (1 << maxc) - 1); i++) {
    int from = i / 2;
    for (auto itr = ma[from].begin(); itr != ma[from].end(); itr++) {
      int weight = itr->first;
      int value = itr->second;
      if (ma[i].find(weight) != ma[i].end()) {
        ma[i][weight] = max(ma[i][weight], value);
      } else {
        ma[i][weight] = value;
      }
      if (ma[i].find(weight + w[i]) != ma[i].end()) {
        ma[i][weight + w[i]] = max(ma[i][weight + w[i]], value + v[i]);
      } else {
        ma[i][weight + w[i]] = value + v[i];
      }
    }
    int now = 0;
    for (auto itr = ma[i].begin(); itr != ma[i].end(); itr++) {
      now = max(now, itr->second);
      itr->second = now;
    }
  }
  int q;
  cin >> q;
  while (q--) {
    int vertex, l;
    cin >> vertex >> l;
    if (vertex < (1 << maxc)) {
      auto itr = ma[vertex].upper_bound(l);
      itr--;
      cout << (itr->second);
    } else {
      vector<p> vec; // 重さ、価値
      int vv = vertex;
      while (vv >= (1 << maxc)) {
        vec.push_back(p(w[vv], v[vv]));
        vv /= 2;
      }
      int ans = 0;
      for (int i = 0; i < (1 << vec.size()); i++) {
        int weight = 0;
        int value = 0;
        for (int x = 0; x < vec.size(); x++) {
          if ((i >> x) & 1) {
            weight += vec[x].first;
            value += vec[x].second;
          }
        }
        if (weight <= l) {
          auto itr = ma[vv].upper_bound(l - weight);
          itr--;
          ans = max(ans, value + itr->second);
        }
      }
      cout << ans;
    }
    cout << "\n";
  }
}


Fixed submission:
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstring>
#include <float.h>
#include <fstream>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>
using namespace std;
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
  using P = function<OperatorMonoid(OperatorMonoid, int)>;

  int sz;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const P p;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const P p,
                  const Monoid &M1, const OperatorMonoid OM0)
      : f(f), g(g), h(h), p(p), M1(M1), OM0(OM0) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  void propagate(int k, int len) {
    if (lazy[k] != OM0) {
      if (k < sz) {
        lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
        lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      }
      data[k] = g(data[k], p(lazy[k], len));
      lazy[k] = OM0;
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return data[k];
    } else if (a <= l && r <= b) {
      lazy[k] = h(lazy[k], x);
      propagate(k, r - l);
      return data[k];
    } else {
      return data[k] = f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
                         update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid update(int a, int b, const OperatorMonoid &x) {
    return update(a, b, x, 1, 0, sz);
  }

  Monoid query(int a, int b, int k, int l, int r) {
    propagate(k, r - l);
    if (r <= a || b <= l) {
      return M1;
    } else if (a <= l && r <= b) {
      return data[k];
    } else {
      return f(query(a, b, 2 * k + 0, l, (l + r) >> 1),
               query(a, b, 2 * k + 1, (l + r) >> 1, r));
    }
  }

  Monoid query(int a, int b) { return query(a, b, 1, 0, sz); }

  Monoid operator[](const int &k) { return query(k, k + 1); }
};
map<int64_t, int> prime_factor(int64_t n) {
  map<int64_t, int> ret;
  for (int64_t i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      ret[i]++;
      n /= i;
    }
  }
  if (n != 1)
    ret[n] = 1;
  return ret;
}
long long MOD = 998244353;
const int MAX = 510000;
long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
template <typename T> struct BinaryIndexedTree {
  vector<T> data;

  BinaryIndexedTree(int sz) { data.assign(++sz, 0); }

  T sum(int k) {
    T ret = 0;
    for (++k; k > 0; k -= k & -k)
      ret += data[k];
    return (ret);
  }

  void add(int k, T x) {
    for (++k; k < data.size(); k += k & -k)
      data[k] += x;
  }
};
typedef pair<int, int> p;
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int maxc = 11;
  int n;
  cin >> n;
  int v[300004];
  int w[300004];
  for (int i = 1; i <= n; i++) {
    cin >> v[i] >> w[i];
  }
  map<int, int> ma[3000004]; // i番目の頂点の重さx以下のときの最大価値
  ma[1][0] = 0;
  ma[1][w[1]] = v[1];
  for (int i = 2; i <= min(n, (1 << maxc) - 1); i++) {
    int from = i / 2;
    for (auto itr = ma[from].begin(); itr != ma[from].end(); itr++) {
      int weight = itr->first;
      int value = itr->second;
      if (ma[i].find(weight) != ma[i].end()) {
        ma[i][weight] = max(ma[i][weight], value);
      } else {
        ma[i][weight] = value;
      }
      if (ma[i].find(weight + w[i]) != ma[i].end()) {
        ma[i][weight + w[i]] = max(ma[i][weight + w[i]], value + v[i]);
      } else {
        ma[i][weight + w[i]] = value + v[i];
      }
    }
    int now = 0;
    for (auto itr = ma[i].begin(); itr != ma[i].end(); itr++) {
      now = max(now, itr->second);
      itr->second = now;
    }
  }
  int q;
  cin >> q;
  while (q--) {
    int vertex, l;
    cin >> vertex >> l;
    if (vertex < (1 << maxc)) {
      auto itr = ma[vertex].upper_bound(l);
      itr--;
      cout << (itr->second);
    } else {
      vector<p> vec; // 重さ、価値
      int vv = vertex;
      while (vv >= (1 << maxc)) {
        vec.push_back(p(w[vv], v[vv]));
        vv /= 2;
      }
      int ans = 0;
      for (int i = 0; i < (1 << vec.size()); i++) {
        int weight = 0;
        int value = 0;
        for (int x = 0; x < vec.size(); x++) {
          if ((i >> x) & 1) {
            weight += vec[x].first;
            value += vec[x].second;
          }
        }
        if (weight <= l) {
          auto itr = ma[vv].upper_bound(l - weight);
          itr--;
          ans = max(ans, value + itr->second);
        }
      }
      cout << ans;
    }
    cout << "\n";
  }
}