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

#include <bits/stdc++.h>
// using namespace std;
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define rep(i, j, n) for (ll i = (ll)(j); i < (ll)(n); i++)
#define REP(i, j, n) for (ll i = (ll)(j); i <= (ll)(n); i++)
#define per(i, j, n) for (ll i = (ll)(j); (ll)(n) <= i; i--)
#define ll long long
#define ALL(a) (a).begin(), (a).end()
#define disup(A, key) distance(A.begin(), upper_bound(ALL(A), (ll)(key)))
#define dislow(A, key) distance(A.begin(), lower_bound(ALL(A), (ll)(key)))
#define pb emplace_back
#define mp std::make_pair
#define endl "\\n"
// using std::endl;
using std::cin;
using std::cout;
using std::lower_bound;
using std::string;
using std::upper_bound;
using std::vector;
using vi = vector<ll>;
using vii = vector<vi>;
using pii = std::pair<ll, ll>;
// constexpr
ll MOD = 1e9 + 7;
// constexpr ll MOD=998244353;
// constexpr ll MOD=10000000;
constexpr ll MAX = 1e6;
constexpr ll INF = (1ll << 62);
template <class T>
class prique : public std::priority_queue<T, std::vector<T>, std::greater<T>> {
};
struct Segment_tree {
  ll N;
  vector<pii> node;
  Segment_tree(ll sz) {
    N = 1;
    while (N < sz)
      N *= 2;
    node.resize(2 * N - 1, mp(INF, INF));
    per(i, N - 2, 0) { node[i] = std::min(node[i * 2 + 1], node[i * 2 + 1]); }
  }
  void update(ll X, pii val) {
    X += N - 1;
    node[X] = val;
    while (X > 0) {
      X = (X - 1) / 2;
      node[X] = std::min(node[X * 2 + 1], node[X * 2 + 2]);
    }
  }
  pii RMQ(ll a, ll b, ll now, ll l, ll r) { //[a,b),[l,r)
    if (r < 0)
      r = N;
    if (r <= a || b <= l)
      return mp(INF, INF);
    if (a <= l && r <= b)
      return node[now];
    auto vl = RMQ(a, b, now * 2 + 1, l, (l + r) / 2),
         vr = RMQ(a, b, now * 2 + 2, (l + r) / 2, r);
    return std::min(vl, vr);
  }
};
struct Binary_indexed_tree {
  int N;
  vi bit;
  Binary_indexed_tree(int n) : N(n) { bit.resize(N + 1, 0); }
  void add(int x, int a) {
    for (x; x <= N; x += (x & -x))
      bit[x] += a;
  }
  ll sum(int x) {
    ll ret = 0;
    for (x; x > 0; x -= (x & -x))
      ret += bit[x];
    return ret;
  }
  ll lower_bound(ll X) {
    if (sum(N) < X)
      return -1;
    ll ret = 0, memo = 1, sum = 0;
    while (memo * 2 <= N)
      memo *= 2;
    while (memo > 0) {
      if (memo + ret <= N && sum + bit[memo + ret] < X) {
        sum += bit[memo + ret];
        ret += memo;
      }
      memo /= 2;
    }
    return ret + 1;
  }
};
struct Union_Find {
  ll N;
  vi par;
  vi siz;
  Union_Find(int n) : N(n) {
    par.resize(N);
    siz.resize(N, 1);
    rep(i, 0, N) par[i] = i;
  }
  ll root(ll X) {
    if (par[X] == X)
      return X;
    return par[X] = root(par[X]);
  }
  bool same(ll X, ll Y) { return root(X) == root(Y); }
  void unite(ll X, ll Y) {
    X = root(X);
    Y = root(Y);
    if (X == Y)
      return;
    par[X] = Y;
    siz[Y] += siz[X];
    siz[X] = 0;
  }
  ll size(ll X) { return siz[root(X)]; }
};
long long modpow(long long a, long long n, long long mod) {
  long long res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
vi fac, finv, inv;
void COMinit() {
  fac.resize(MAX);
  finv.resize(MAX);
  inv.resize(MAX);
  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;
  }
}
ll COM(ll n, ll r) {
  if (n < r || n < 0 || r < 0)
    return 0;
  return fac[n] * finv[r] % MOD * finv[n - r] % MOD;
}
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  ll N, Q;
  cin >> N;
  vi V(N + 1), W(N + 1);
  REP(i, 1, N) cin >> V[i] >> W[i];
  ll M = 0;
  while (1) {
    if ((1ll << M) * (1ll << M) > N)
      break;
    M++;
  }
  vector<std::map<ll, ll>> memo((1ll << M));
  rep(i, 0, (1ll << M)) {
    ll X = (1ll << M) + i;
    if (X > N)
      break;
    vi A, B;
    while (X > 0) {
      A.pb(V[X]), B.pb(W[X]);
      X /= 2;
    }
    rep(j, 0, (1ll << A.size())) {
      ll v = 0, w = 0;
      rep(k, 0, A.size()) {
        if (((1ll << k) & j) == 0)
          w += B[k], v += A[k];
      }
      memo[i][w] = std::max(memo[i][w], v);
    }
    ll max = 0;
    for (auto p : memo[i]) {
      max = std::max(max, p.second);
      memo[i][p.first] = max;
    }
    memo[i][INF] = 0;
  }
  cin >> Q;
  rep(_, 0, Q) {
    ll ans = 0;
    ll X, L;
    cin >> X >> L;
    if ((1ll << M) > X) {
      vi A, B;
      while (X > 0) {
        A.pb(V[X]), B.pb(W[X]);
        X /= 2;
      }
      rep(j, 0, (1ll << A.size())) {
        ll v = 0, w = 0;
        rep(k, 0, A.size()) {
          if (((1ll << k) & j) == 0)
            w += B[k], v += A[k];
        }
        if (w <= L)
          ans = std::max(ans, v);
      }
    } else if ((1ll << M + 1) <= X) {
      vi A, B;
      while (X >= (1ll << M + 1)) {
        A.pb(V[X]), B.pb(W[X]);
        X /= 2;
      }
      X -= (1ll << M);
      rep(j, 0, (1ll << A.size())) {
        ll v = 0, w = 0;
        rep(k, 0, A.size()) {
          if (((1ll << k) & j) == 0)
            w += B[k], v += A[k];
        }
        auto it = memo[X].upper_bound(L - w);
        if (it == begin(memo[X]))
          continue;
        it--;
        pii p = *it;
        ans = std::max(ans, p.second + v);
      }
    } else {
      auto it = memo[X - (1ll << M)].upper_bound(L);
      it--;
      pii p = *it;
      ans = p.second;
    }
    cout << ans << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
// using namespace std;
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define rep(i, j, n) for (ll i = (ll)(j); i < (ll)(n); i++)
#define REP(i, j, n) for (ll i = (ll)(j); i <= (ll)(n); i++)
#define per(i, j, n) for (ll i = (ll)(j); (ll)(n) <= i; i--)
#define ll int
#define ALL(a) (a).begin(), (a).end()
#define disup(A, key) distance(A.begin(), upper_bound(ALL(A), (ll)(key)))
#define dislow(A, key) distance(A.begin(), lower_bound(ALL(A), (ll)(key)))
#define pb emplace_back
#define mp std::make_pair
#define endl "\\n"
// using std::endl;
using std::cin;
using std::cout;
using std::lower_bound;
using std::string;
using std::upper_bound;
using std::vector;
using vi = vector<ll>;
using vii = vector<vi>;
using pii = std::pair<long long, long long>;
/*//constexpr
ll MOD=1e9+7;
//constexpr ll MOD=998244353;
//constexpr ll MOD=10000000;
constexpr ll MAX=1e6;
constexpr ll INF=(1ll<<62);
template<class T>
class prique :public std::priority_queue<T, std::vector<T>, std::greater<T>> {};
struct Segment_tree{
    ll N;
    vector<pii> node;
    Segment_tree(ll sz){
        N=1;
        while(N<sz) N*=2;
        node.resize(2*N-1,mp(INF,INF));
        per(i,N-2,0){
            node[i]=std::min(node[i*2+1],node[i*2+1]);
        }
    }
    void update(ll X,pii val){
        X+=N-1;
        node[X]=val;
        while(X>0){
            X=(X-1)/2;
            node[X]=std::min(node[X*2+1],node[X*2+2]);
        }
    }
    pii RMQ(ll a,ll b,ll now,ll l,ll r){ //[a,b),[l,r)
        if(r<0) r=N;
        if(r<=a||b<=l) return mp(INF,INF);
        if(a<=l&&r<=b) return node[now];
        auto vl=RMQ(a,b,now*2+1,l,(l+r)/2),vr=RMQ(a,b,now*2+2,(l+r)/2,r);
        return std::min(vl,vr);
    }
};
struct Binary_indexed_tree{
    int N;
    vi bit;
    Binary_indexed_tree(int n):N(n){
        bit.resize(N+1,0);
    }
    void add(int x,int a){
        for(x;x<=N;x+=(x&-x)) bit[x]+=a;
    }
    ll sum(int x){
        ll ret=0;
        for(x;x>0;x-=(x&-x)) ret+=bit[x];
        return ret;
    }
    ll lower_bound(ll X){
        if(sum(N)<X) return -1;
        ll ret=0,memo=1,sum=0;
        while(memo*2<=N) memo*=2;
        while(memo>0){
            if(memo+ret<=N&&sum+bit[memo+ret]<X){
                sum+=bit[memo+ret];
                ret+=memo;
            }
            memo/=2;
        }
        return ret+1;
    }
};
struct Union_Find{
    ll N;
    vi par;
    vi siz;
    Union_Find(int n):N(n){
        par.resize(N);
        siz.resize(N,1);
        rep(i,0,N) par[i]=i;
    }
    ll root(ll X){
        if(par[X]==X) return X;
        return par[X]=root(par[X]);
    }
    bool same(ll X,ll Y){
        return root(X)==root(Y);
    }
    void unite(ll X,ll Y){
        X=root(X);
        Y=root(Y);
        if(X==Y) return;
        par[X]=Y;
        siz[Y]+=siz[X];
        siz[X]=0;
    }
    ll size(ll X){
        return siz[root(X)];
    }
};
long long modpow(long long a, long long n, long long mod) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
vi fac,finv,inv;
void COMinit() {
    fac.resize(MAX);
    finv.resize(MAX);
    inv.resize(MAX);
    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;
    }
}
ll COM(ll n,ll r){
    if(n<r||n<0||r<0) return 0;
    return fac[n]*finv[r]%MOD*finv[n-r]%MOD;
}*/
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  ll N, Q;
  cin >> N;
  vi V(N + 1), W(N + 1);
  REP(i, 1, N) cin >> V[i] >> W[i];
  ll M = 0;
  while (1) {
    if ((1ll << M + 1) > N)
      break;
    M++;
  }
  vector<std::map<ll, long long>> memo((1ll << M));
  rep(i, 0, (1ll << M)) {
    ll X = (1ll << M) + i;
    if (X > N)
      break;
    vi A, B;
    while (X > 0) {
      A.pb(V[X]), B.pb(W[X]);
      X /= 2;
    }
    rep(j, 0, (1ll << A.size())) {
      long long v = 0, w = 0;
      rep(k, 0, A.size()) {
        if (((1ll << k) & j) == 0)
          w += B[k], v += A[k];
      }
      if (w > 100000)
        continue;
      memo[i][w] = std::max(memo[i][w], v);
    }
    long long max = -1;
    vi a;
    for (auto p : memo[i]) {
      if (max >= p.second) {
        a.pb(p.first);
        continue;
      }
      max = std::max(max, p.second);
      memo[i][p.first] = max;
    }
    rep(j, 0, a.size()) memo[i].erase(a[j]);
    memo[i][1000000] = 0;
  }
  cin >> Q;
  rep(_, 0, Q) {
    long long ans = 0;
    ll X, L;
    cin >> X >> L;
    if ((1ll << M) > X) {
      vi A, B;
      while (X > 0) {
        A.pb(V[X]), B.pb(W[X]);
        X /= 2;
      }
      rep(j, 0, (1ll << A.size())) {
        long long v = 0, w = 0;
        rep(k, 0, A.size()) {
          if (((1ll << k) & j) == 0)
            w += B[k], v += A[k];
        }
        if (w <= L)
          ans = std::max(ans, v);
      }
    } else if ((1ll << M + 1) <= X) {
      vi A, B;
      while (X >= (1ll << M + 1)) {
        A.pb(V[X]), B.pb(W[X]);
        X /= 2;
      }
      X -= (1ll << M);
      rep(j, 0, (1ll << A.size())) {
        long long v = 0, w = 0;
        rep(k, 0, A.size()) {
          if (((1ll << k) & j) == 0)
            w += B[k], v += A[k];
        }
        auto it = memo[X].upper_bound(L - w);
        if (it == begin(memo[X]))
          continue;
        it--;
        pii p = *it;
        ans = std::max(ans, p.second + v);
      }
    } else {
      auto it = memo[X - (1ll << M)].upper_bound(L);
      it--;
      pii p = *it;
      ans = p.second;
    }
    cout << ans << endl;
  }
}