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: Runtime Error)

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;

    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();
        }

        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false});


        Q = sc.NextInt();
        for (int i = 0; i < Q; i++)
        {
            Query(sc);
        }

        Console.Out.Flush();
    }

    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 <= 11)
        {
            // 普通に列挙
            long ans = 0;
            int cur = v;
            var ls = new List<S>();
            ls.Add(new S(0, 0));
            for (int i = 0; i < depth; i++, cur /= 2)
            {
                int len = ls.Count;
                for (int j = 0; j < len; j++)
                {
                    if (ls[j].W + W[cur - 1] <= L)
                    {
                        ans = Math.Max(ans, ls[j].V + V[cur - 1]);
                        ls.Add(new S(ls[j].V + V[cur - 1], ls[j].W + W[cur - 1]));
                    }
                }
            }

            Console.WriteLine(ans);
        }
        else
        {
            // depth-11個上まで
            var lsA = new List<S>();
            lsA.Add(new S(0, 0));
            int cur = v;

            for (int i = 0; i < depth - 11; cur /= 2, i++)
            {
                int len = lsA.Count;
                for (int j = 0; j < len; j++)
                {
                    if (lsA[j].W + W[cur - 1] <= L) lsA.Add(new S(lsA[j].V + V[cur - 1], lsA[j].W + W[cur - 1]));
                }
            }

            lsA.Sort((l, r) => l.W == r.W ? r.V.CompareTo(l.V) : l.W.CompareTo(r.W));

            var a = new List<S>();
            long max = long.MinValue;
            foreach (S pair in lsA)
            {
                if (pair.V <= max) continue;
                a.Add(pair);
                max = pair.V;
            }

            // depth=11から根まで

            var lsB = new List<S>();
            lsB.Add(new S(0, 0));
            for (int i = 0; i < 11; i++, cur /= 2)
            {
                int len = lsA.Count;
                for (int j = 0; j < len; j++)
                {
                    if (lsB[j].W + W[cur - 1] <= L) lsB.Add(new S(lsB[j].V + V[cur - 1], lsB[j].W + W[cur - 1]));
                }
            }

            lsB.Sort((l, r) => l.W == r.W ? r.V.CompareTo(l.V) : l.W.CompareTo(r.W));

            var b = new List<S>();
            max = long.MinValue;
            foreach (S pair in lsB)
            {
                if (pair.V <= max) continue;
                b.Add(pair);
                max = pair.V;
            }

            long ans = long.MinValue;

            foreach (S pair in a)
            {
                int ok = 0;
                int ng = b.Count;
                while (ng - ok > 1)
                {
                    int mid = (ok + ng) / 2;
                    if (b[mid].W + pair.W <= L) ok = mid;
                    else ng = mid;
                }

                ans = Math.Max(ans, pair.V + b[ok].V);
            }

            Console.WriteLine(ans);
        }
    }

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

struct S
{
    public long V, W;

    public S(long v, long 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();
    }
}