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 Rust (1.42.0) (judge verdict: Time Limit Exceeded)

//! Framework <https://github.com/vain0x/procon>

#![allow(non_snake_case)]
#![allow(unused_imports)]

use std::collections::*;

pub struct Scan(Box<dyn Iterator<Item = &'static str>>); // '

impl Scan {
    fn new() -> Self {
        let mut buf = String::new();
        let read_line = move || {
            std::io::stdin().read_line(&mut buf).unwrap();
            Box::leak(buf.split_off(0).into_boxed_str()).split_whitespace()
        };
        Scan(Box::new(std::iter::repeat_with(read_line).flatten()))
    }

    pub fn word<T: std::str::FromStr>(&mut self) -> T {
        self.0.next().unwrap().parse().ok().unwrap()
    }

    pub fn list<T: std::str::FromStr>(&mut self, len: usize) -> Vec<T> {
        std::iter::repeat_with(|| self.word()).take(len).collect()
    }
}

#[derive(Default)]
struct Solve {
    N: usize,
    V: Vec<usize>,
    W: Vec<usize>,
    Q: usize,
    v: Vec<usize>,
    L: Vec<usize>,
    dp: Vec<Vec<usize>>,
    qs: Vec<Vec<(usize, usize)>>,
    rs: Vec<usize>,
    ls: Vec<usize>,
}

impl Solve {
    fn solve(mut self) {
        let N = self.N;
        let Q = self.Q;

        self.rs.resize(Q, 0);
        self.qs.resize(N, vec![]);
        self.ls.resize(N, 0);

        // let mut ml = 0;

        for q in 0..Q {
            let u = self.v[q];
            let l = self.L[q];

            self.qs[u].push((l, q));
            self.ls[u] = self.ls[u].max(l);
            // ml = ml.max(l);
        }

        // self.ls.resize(N, ml);
        self.dfs_l(0);

        self.dfs_r(0);

        for q in 0..Q {
            println!("{}", self.rs[q]);
        }
    }

    fn dfs_l(&mut self, u: usize) -> usize {
        if u >= self.N {
            return 0;
        }

        if u >= 1 {
            self.ls[u] = self.ls[u].max(self.ls[(u - 1) / 2]);
        }

        let w = self.ls[u]
            .max(self.dfs_l(u * 2 + 1))
            .max(self.dfs_l(u * 2 + 2));
        self.ls[u] = w;
        w
    }

    fn dfs_r(&mut self, u: usize) {
        if u >= self.N {
            return;
        }

        let l = self.ls[u];
        let h = self.dp.len();
        self.dp.push(vec![0; l + 1]);

        if u == 0 {
            if self.W[u] <= l {
                self.dp[h][self.W[u]] += self.V[u];
            }
        } else {
            for w in 0..=l {
                self.dp[h][w] = self.dp[h][w].max(self.dp[h - 1][w]);

                if w + self.W[u] <= l {
                    self.dp[h][w + self.W[u]] =
                        self.dp[h][w + self.W[u]].max(self.dp[h - 1][w] + self.V[u]);
                }
            }
        }

        for w in 1..=l {
            self.dp[h][w] = self.dp[h][w].max(self.dp[h][w - 1]);
        }

        for &(w, q) in &self.qs[u] {
            self.rs[q] = self.dp[h][w];
        }

        self.dfs_r(u * 2 + 1);
        self.dfs_r(u * 2 + 2);

        self.dp.pop();
    }
}

fn main() {
    let mut scan = Scan::new();

    let N = scan.word::<usize>();
    let mut V = vec![0; N];
    let mut W = vec![0; N];

    for i in 0..N {
        V[i] = scan.word::<usize>();
        W[i] = scan.word::<usize>();
    }

    let Q = scan.word::<usize>();
    let mut v = vec![0; Q];
    let mut L = vec![0; Q];

    for q in 0..Q {
        v[q] = scan.word::<usize>() - 1;
        L[q] = scan.word::<usize>();
    }

    Solve {
        N,
        V,
        W,
        Q,
        v,
        L,
        ..Solve::default()
    }
    .solve();
}