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: Wrong Answer)

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.IO.MemoryMappedFiles;

namespace AtCoder.Contest.D
{
	static class Program
	{
		public static void Main(string[] args)
		{
			var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
			Console.SetOut(sw);

			var cin = new Scanner();

			int n = cin.NextInt();
			int depth = 0;
			int k = n;
			while (k > 0)
			{
				k /= 2;
				depth++;
			}
			var v = new List<int>();
			var w = new List<int>();
			for (int i = 0; i < n; i++)
			{
				v.Add(cin.NextInt());
				w.Add(cin.NextInt());
			}

			var memo = new int[xy((1 << (depth / 2)), 100005)];
			for (int i = 0; i < (1 << (depth / 2)); i++)
			{
				for (int j = 0; j < 100005; j++)
				{
					if (i == 0)
					{
						if (j < w[i]) memo[xy(i, j)] = 0;
						else memo[xy(i, j)] = v[i];
					}
					else
					{
						if (j < w[i]) memo[xy(i, j)] = memo[xy((i - 1) / 2, j)];
						else memo[xy(i, j)] = Math.Max(memo[xy((i - 1) / 2, j)], memo[xy((i - 1) / 2, j - w[i])] + v[i]);
					}
				}
			}

			int q = cin.NextInt();
			for (int i = 0; i < q; i++)
			{
				int p = cin.NextInt() - 1;
				int l = cin.NextInt();
				if (n == 1)
				{
					if (w[0] <= l) Console.WriteLine(v[0]);
					else Console.WriteLine(0);
				}
				else
				{
					int kk = p + 1;
					int depthp = 0;
					while (kk > 0)
					{
						kk /= 2;
						depthp++;
					}
					if (depthp < depth / 2)
					{
						Console.WriteLine(memo[xy(p, l)]);
					}
					else
					{
						var list = new List<Pair<int, int>>();
						int ans = 0;
						int _p = p;
						for (int j = 0; j < depthp - depth / 2 + 1; j++, _p = (_p - 1) / 2)
						{
							list.Add(new Pair<int, int>(v[_p], w[_p]));
						}
						for (int bit = 0; bit < 1 << (depthp - depth / 2 + 1); bit++)
						{
							int weight = 0;
							int value = 0;
							for (int s = 0; s < depthp - depth / 2; s++)
							{
								if ((bit / (1 << s)) % 2 == 1)
								{
									value += list[s].First;
									weight += list[s].Second;
								}
							}
							if (weight > l) continue;
							ans = Math.Max(ans, memo[xy(_p, l - weight)] + value);
						}
						Console.WriteLine(ans);
					}
				}
			}

			Console.Out.Flush();
		}
		public static int xy(int x, int y) => x * 100005 + y;
	}

	public class Pair<T, U> : IComparable, IEquatable<Pair<T, U>> where T : IComparable<T>, IEquatable<T> where U : IComparable<U>, IEquatable<U>
	{
		public T First { get; set; }
		public U Second { get; set; }

		public Pair(T first, U second)
		{
			First = first;
			Second = second;
		}

		public int CompareTo(object obj)
		{
			Pair<T, U> castedObj = (Pair<T, U>)obj;
			int x = First.CompareTo(castedObj.First);
			if (x != 0) return x;
			else return Second.CompareTo(castedObj.Second);
		}

		public static bool operator ==(Pair<T, U> x, Pair<T, U> y) => x.CompareTo(y) == 0;

		public static bool operator !=(Pair<T, U> x, Pair<T, U> y) => x.CompareTo(y) != 0;

		public static bool operator <(Pair<T, U> x, Pair<T, U> y) => x.CompareTo(y) == 1;

		public static bool operator >(Pair<T, U> x, Pair<T, U> y) => x.CompareTo(y) == -1;

		public static bool operator <=(Pair<T, U> x, Pair<T, U> y) => x.CompareTo(y) > 0;

		public static bool operator >=(Pair<T, U> x, Pair<T, U> y) => x.CompareTo(y) < 0;

		public bool Equals(Pair<T, U> x) => First.Equals(x.First) && Second.Equals(x.Second);

		public override bool Equals(object obj)
		{
			return obj is Pair<T, U> pair &&
				   EqualityComparer<T>.Default.Equals(First, pair.First) &&
				   EqualityComparer<U>.Default.Equals(Second, pair.Second);
		}

		public override int GetHashCode()
		{
			unchecked
			{
				var hashCode = 405212230;
				hashCode = hashCode * -1521134295 + EqualityComparer<T>.Default.GetHashCode(First);
				hashCode = hashCode * -1521134295 + EqualityComparer<U>.Default.GetHashCode(Second);
				return hashCode;
			}
		}
	}

	class Scanner
	{
		string[] s;
		int i;

		char[] cs = new char[] { ' ' };

		public Scanner()
		{
			s = new string[0];
			i = 0;
		}

		public string Next()
		{
			if (i < s.Length) return s[i++];
			string st = Console.ReadLine();
			while (st == "") st = Console.ReadLine();
			s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			if (s.Length == 0) return Next();
			i = 0;
			return s[i++];
		}

		public int NextInt()
		{
			return int.Parse(Next());
		}

		public int[] ArrayInt(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = NextInt() + add;
			}
			return Array;
		}

		public long NextLong()
		{
			return long.Parse(Next());
		}

		public long[] ArrayLong(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = NextLong() + add;
			}
			return Array;
		}

		public double NextDouble()
		{
			return double.Parse(Next());
		}

		public double[] ArrayDouble(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = NextDouble() + add;
			}
			return Array;
		}
	}
}