Problem:
Score : 700 points

Problem Statement

We have a rooted binary tree with N vertices, where the vertices are numbered 1 to N.
Vertex 1 is the root, and the parent of Vertex i (i \geq 2) is Vertex \left[ \frac{i}{2} \right].

Each vertex has one item in it. The item in Vertex i has a value of V_i and a weight of W_i.
Now, process the following query Q times:

Given are a vertex v of the tree and a positive integer L.
Let us choose some (possibly none) of the items in v and the ancestors of v so that their total weight is at most L.
Find the maximum possible total value of the chosen items.

Here, Vertex u is said to be an ancestor of Vertex v when u is an indirect parent of v, that is, there exists a sequence of vertices w_1,w_2,\ldots,w_k (k\geq 2) where w_1=v, w_k=u, and w_{i+1} is the parent of w_i for each i.

Constraints

All values in input are integers.

1 \leq N < 2^{18}

1 \leq Q \leq 10^5

1 \leq V_i \leq 10^5

1 \leq W_i \leq 10^5

For the values v and L given in each query, 1 \leq v \leq N and 1 \leq L \leq 10^5.

Input

Let v_i and L_i be the values v and L given in the i-th query.
Then, Input is given from Standard Input in the following format:

N
V_1 W_1
:
V_N W_N
Q
v_1 L_1
:
v_Q L_Q

Output

For each integer i from 1 through Q,
the i-th line should contain the response to the i-th query.

Sample Input 1

3
1 2
2 3
3 4
3
1 1
2 5
3 5

Sample Output 1

0
3
3

In the first query, we are given only one choice: the item with (V, W)=(1,2). Since L = 1, we cannot actually choose it, so our response should be 0.

In the second query, we are given two choices: the items with (V, W)=(1,2) and (V, W)=(2,3). Since L = 5, we can choose both of them, so our response should be 3.

Sample Input 2

15
123 119
129 120
132 112
126 109
118 103
115 109
102 100
130 120
105 105
132 115
104 102
107 107
127 116
121 104
121 115
8
8 234
9 244
10 226
11 227
12 240
13 237
14 206
15 227

Sample Output 2

256
255
250
247
255
259
223
253

Solution in C++ (Clang 10.0.0) (judge verdict: Wrong Answer)


#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <queue>
#include <vector>

using namespace std;

constexpr static int MAXN = 3e5 + 10;
constexpr static int MAXL = 1e5 + 10;
constexpr static int N1 = (1 << 9);

int n;
int v[MAXN], w[MAXN];
vector <pair <int, int>> dp[N1];

void dp_step(const vector <pair <int, int>>& cur,
        vector <pair <int, int>>& nxt, int u, int L) {
    const auto& a = cur;
    vector <pair <int, int>> b;
    for (auto p : cur)
        if (p.first + w[u] <= L)
            b.push_back({p.first + w[u], p.second + v[u]});

    int i = 0, j = 0;
    while (i < a.size() && j < b.size()) {
        if (a[i].first < b[j].first) {
            if (nxt.size() == 0 || a[i].second > nxt.back().second)
                nxt.push_back(a[i]);
            i++;
        }
        else if (a[i].first > b[j].first) {
            if (nxt.size() == 0 || b[j].second > nxt.back().second)
                nxt.push_back(b[j]);
            j++;
        }
        else {
            int vmax = max(a[i].second, b[j].second);
            if (nxt.size() == 0 || vmax > nxt.back().second)
                nxt.push_back({a[i].first, vmax});
            i++, j++;
        }
    }
    while (i < a.size())
        nxt.push_back(a[i++]);
    while (j < b.size())
        nxt.push_back(b[j++]);
}

void init() {
    dp[0].push_back({0, 0});
    for (int i = 1; i <= n && i < N1; i++)
        dp_step(dp[i >> 1], dp[i], i, MAXL);
}

int query(int u, int L) {
    vector <pair <int, int>> cur, nxt;
    cur.push_back({0, 0});
    while (u >= N1) {
        if (w[u] <= L) {
            dp_step(cur, nxt, u, L);
            cur = nxt;
            nxt.clear();
        }
        u /= 2;
    }

    const auto& a = dp[u];
    const auto& b = cur;
    int j = b.size() - 1;
    int vmax = 0;
    for (int i = 0; i < a.size(); i++) {
        while (j > 0 && a[i].first + b[j].first > L)
            j--;
        if (a[i].first + b[j].first <= L)
            vmax = max(vmax, a[i].second + b[j].second);
    }

    return vmax;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> v[i] >> w[i];

    init();

    int q;
    cin >> q;
    while (q--) {
        int u, L;
        cin >> u >> L;
        cout << query(u, L) << '\n';
    }
}