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# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.IO;
using CompLib.Util;

public class Program
{
    private int N;
    private int[] V, W;
    private int Q;

    // 頂点iで重さがj以下での価値最大
    private long[] D;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        V = new int[N];
        W = new int[N];
        for (int i = 0; i < N; i++)
        {
            V[i] = sc.NextInt();
            W[i] = sc.NextInt();
        }

        int p = Math.Min(N + 1, 1 << 10);
        D = new long[p * 100001];
        SetD(1, 1);
        Q = sc.NextInt();
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false});
        for (int i = 0; i < Q; i++)
        {
            Query(sc);
        }

        Console.Out.Flush();
    }

    int C(int i, int j)
    {
        return i * (100001) + j;
    }

    void SetD(int i, int depth)
    {
        if (i > N || depth > 10)
        {
            return;
        }

        for (int j = 0; j <= 100000; j++)
        {
            D[C(i, j)] = D[C(i / 2, j)];
        }

        for (int j = 100000 - W[i - 1]; j >= 0; j--)
        {
            D[C(i, j + W[i - 1])] = Math.Max(D[C(i, j + W[i - 1])], D[C(i / 2, j)] + V[i - 1]);
        }

        SetD(i * 2, depth + 1);
        SetD(i * 2 + 1, depth + 1);
    }

    void Query(Scanner sc)
    {
        int v = sc.NextInt();
        int L = sc.NextInt();

        int depth = 0;
        int cp = v;
        while (cp > 0)
        {
            depth++;
            cp /= 2;
        }

        if (depth <= 10)
        {
            Console.WriteLine(D[C(v, L)]);
            return;
        }

        long ans = 0;
        var ls = new List<S>();
        ls.Add(new S(0, 0));
        int cur = v;
        for (int i = 0; i < depth - 10; i++, cur /= 2)
        {
            int len = ls.Count;
            for (int j = 0; j < len; j++)
            {
                if (ls[j].W + W[cur - 1] <= L)
                {
                    ls.Add(new S(ls[j].V + V[cur - 1], ls[j].W + W[cur - 1]));
                }
            }
        }

        foreach (S pair in ls)
        {
            ans = Math.Max(ans, pair.V + D[C(cur, L - pair.W)]);
        }

        Console.WriteLine(ans);
    }

    public static void Main(string[] args) => new Program().Solve();
}

struct S
{
    public int V, W;

    public S(int v, int w)
    {
        V = v;
        W = w;
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}