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



Sample input:
3
1 2
2 3
3 4
3
1 1
2 5
3 5


Sample output:
0
3
3

Submission status: Accepted

Solution code:
def main():
    import sys
    input = sys.stdin.readline

    n = int(input())

    L_MAX = 10**5
    D_TH = 10
    V_MAX = (1 << D_TH) - 1
    dp = [[0] * (L_MAX + 1)]
    # items = []
    items_v = []
    items_w = []

    for i in range(n):
        val, w = map(int, input().split())
        if i < V_MAX:
            i1 = i + 1
            i0 = (i + 1) >> 1
            dp_ = dp[i0][:]

            # for j in range(w):
            #     dp[i1][j] = dp[i0][j]
            for j in range(w, L_MAX + 1)[::-1]:
                if dp_[j] < dp_[j - w] + val:
                    dp_[j] = dp_[j - w] + val
            dp.append(dp_)
        else:
            # items.append((val, w))
            items_v.append(val)
            items_w.append(w)

    # items = tuple(items)

    q = int(input())
    for _ in range(q):
        v, l = map(int, input().split())
        v -= 1

        if v < V_MAX:
            ans = dp[v + 1][l]
        else:
            vv = []
            ww = []
            while v >= V_MAX:
                # vv.append(items[v - V_MAX][0])
                # ww.append(items[v - V_MAX][1])
                vv.append(items_v[v - V_MAX])
                ww.append(items_w[v - V_MAX])
                v = (v - 1) >> 1

            ans = dp[v + 1][l]
            # m = len(vv)
            m2 = 1 << len(vv)
            v_sub = [0] * m2
            w_sub = [0] * m2
            for bit in range(1, m2):
                bit_min = bit & (-bit)
                x = bit_min.bit_length() - 1

                s_w = w_sub[bit - bit_min] + ww[x]
                w_sub[bit] = s_w
                if s_w <= l:
                    s_val = v_sub[bit - bit_min] + vv[x]
                    v_sub[bit] = s_val
                    ans = max(ans, dp[v + 1][l - s_w] + s_val)

        print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
import bisect
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


def merge(a, b):
    res = []
    i, j = 0, 0
    while i < len(a) or j < len(b):
        if j >= len(b) or (i < len(a) and a[i][0] < b[j][0]):
            w, v = a[i]
            i += 1
        else:
            w, v = b[j]
            j += 1
        if not res or (res[-1][1]) < v:
            res.append((w, v))
        elif res[-1][0] == w and res[-1][1] <= v:
            res.pop()
            res.append((w, v))
    return res


def best(L, a, b):
    res = 0
    i = 0
    j = len(b) - 1
    while i < len(a):
        w, v = a[i]
        if j < 0:
            break
        if b[j][0] + w > L:
            j -= 1
            continue
        res = max(res, v + b[j][1])
        i += 1
    return res


def main():
    N = int(input())
    VW = [(-1, -1)] + [list(map(int, input().split())) for _ in range(N)]
    Q = int(input())
    query = tuple(tuple(map(int, input().split())) for _ in range(Q))

    dp = [[] for _ in range(2048)]
    dp[0] = [(0, 0)]
    for i in range(1, min(N + 1, 2048)):
        vi, wi = VW[i]
        a1 = dp[i // 2]
        a2 = [(w + wi, v + vi) for w, v in a1]
        dp[i] = merge(a1, a2)

    for n, L in query:
        if n < 2048:
            w, v = zip(*dp[n])
            i = bisect.bisect_right(w, L) - 1
            print(v[i])
        else:
            a = [(0, 0)]
            while n >= 2048:
                vi, wi = VW[n]
                b = [(w + wi, v + vi) for w, v in a]
                a = merge(a, b)
                n //= 2
            print(best(L, a, dp[n]))


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
# coding: utf-8
# Your code here!
import sys
read = sys.stdin.read
readline = sys.stdin.readline

#n,k,*a = map(int,read().split())

n, = map(int,readline().split())
vw = [[0,0]]+[list(map(int,readline().split())) for _ in range(n)]

def merge(av,aw,bv,bw):
    la,lb = len(aw),len(bw)
    rv = [0]*(la+lb)
    rw = [0]*(la+lb)
    ia = ib = 0
    for i in range(la+lb):
        if ib==lb or (ia < la and aw[ia] < bw[ib]):
            rv[i] = av[ia]
            rw[i] = aw[ia]
            ia += 1
        else:
            rv[i] = bv[ib]
            rw[i] = bw[ib]
            ib += 1
    return rv,rw

A = 10
N = min(1<<A,n+1)
memov = [[] for _ in range(N)]
memow = [[] for _ in range(N)]

memov[0] = [0]
memow[0] = [0]

#from itertools import acumulate
for i in range(1,N):
    v,w = vw[i]
    m2v = [v+v1 for v1 in memov[i>>1]]
    m2w = [w+w1 for w1 in memow[i>>1]]
    memov[i],memow[i] = merge(memov[i>>1],memow[i>>1],m2v,m2w)

    #memov[i] = list(accumulate(memov[i],max))
    for j in range(1,len(memov[i])):
        memov[i][j] = max(memov[i][j-1],memov[i][j])
    
def solve(lstv,lstw,dv,dw,l):
    ans = 0
    idx = len(lstw)-1
    #print(lstv,lstw,dv,dw,l)
    for v,w in zip(dv,dw):
        while idx >= 0 and lstw[idx] + w > l:
            idx -= 1
        if idx >= 0 and v+lstv[idx] > ans:
            ans = v+lstv[idx]
    print(ans)        
 
 

q, = map(int,readline().split())
for _ in range(q):
    u,l = map(int,readline().split())

    dv = [0]
    dw = [0]
    while u >= N:
        v,w = vw[u]
        m2v = [v+v1 for v1 in dv]
        m2w = [w+w1 for w1 in dw]
        dv,dw = merge(dv,dw,m2v,m2w)
        u >>= 1
    
    #for j in range(1,len(dv)):
    #    dv[j] = max(dv[j-1],dv[j])
    
    solve(memov[u],memow[u],dv,dw,l)

#print(memov)
#print(memow)

Submission status: Accepted

Solution code:
import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

A = 256

def main(N, V, W, v, L):
    def precompute(N, V, W):
        U = 10**5 + 10
        dp = np.zeros((A, U), np.int32)
        for v in range(1, min(A, N + 1)):
            p = v // 2
            dp[v] = dp[p]
            dp[v, W[v]:] = np.maximum(dp[v, W[v]:], dp[p, :-W[v]] + V[v])
            for i in range(1, U):
                dp[v][i] = max(dp[v][i], dp[v][i - 1])
        return dp

    dp = precompute(N, V, W)
    values = np.empty((2**18)//A, np.int32)
    weights = np.empty((2**18)//A, np.int32)

    def solve(i, lim, values, weights, dp):
        if i < A:
            return dp[i][lim]
        values[0] = 0
        weights[0] = 0
        p = 0
        while i >= A:
            for j in range(1 << p):
                values[j + (1 << p)] = values[j] + V[i]
                weights[j + (1 << p)] = weights[j] + W[i]
            p += 1
            i >>= 1
        best = 0
        for n in range(1 << p):
            if weights[n] > lim:
                continue
            x = dp[i][lim - weights[n]] + values[n]
            best = max(best, x)
        return best

    Q = len(v)
    for i in range(Q):
        x = solve(v[i], L[i], values, weights, dp)
        print(x)

        
if sys.argv[-1] == 'ONLINE_JUDGE':
    from numba.pycc import CC
    cc = CC('my_module')
    cc.export('main', '(i4,i4[:],i4[:],i4[:],i4[:])')(main)
    cc.compile()
    exit()

from my_module import main

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2].copy(), query[1::2].copy()

main(N, V, W, v, L)

Submission status: Accepted

Solution code:
import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

A = 1024

def main(N, V, W, v, L):
    def precompute(N, V, W):
        U = 10**5 + 10
        dp = np.zeros((A, U), np.int32)
        for v in range(1, min(A, N + 1)):
            p = v // 2
            dp[v] = dp[p]
            dp[v, W[v]:] = np.maximum(dp[v, W[v]:], dp[p, :-W[v]] + V[v])
            for i in range(1, U):
                dp[v][i] = max(dp[v][i], dp[v][i - 1])
        return dp

    dp = precompute(N, V, W)
    values = np.empty(A, np.int32)
    weights = np.empty(A, np.int32)

    def solve(i, lim, values, weights, dp):
        if i < A:
            return dp[i][lim]
        values[0] = 0
        weights[0] = 0
        p = 0
        while i >= A:
            for j in range(1 << p):
                values[j + (1 << p)] = values[j] + V[i]
                weights[j + (1 << p)] = weights[j] + W[i]
            p += 1
            i >>= 1
        best = 0
        for n in range(1 << p):
            if weights[n] > lim:
                continue
            x = dp[i][lim - weights[n]] + values[n]
            best = max(best, x)
        return best

    Q = len(v)
    for i in range(Q):
        x = solve(v[i], L[i], values, weights, dp)
        print(x)

        
if sys.argv[-1] == 'ONLINE_JUDGE':
    from numba.pycc import CC
    cc = CC('my_module')
    cc.export('main', '(i4,i4[:],i4[:],i4[:],i4[:])')(main)
    cc.compile()
    exit()

from my_module import main

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2].copy(), query[1::2].copy()

main(N, V, W, v, L)

Submission status: Accepted

Solution code:
import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

A = 512

def main(N, V, W, v, L):
    def precompute(N, V, W):
        U = 10**5 + 10
        dp = np.zeros((A, U), np.int32)
        for v in range(1, min(A, N + 1)):
            p = v // 2
            dp[v] = dp[p]
            dp[v, W[v]:] = np.maximum(dp[v, W[v]:], dp[p, :-W[v]] + V[v])
            for i in range(1, U):
                dp[v][i] = max(dp[v][i], dp[v][i - 1])
        return dp

    dp = precompute(N, V, W)
    values = np.empty(A, np.int32)
    weights = np.empty(A, np.int32)

    def solve(i, lim, values, weights, dp):
        if i < A:
            return dp[i][lim]
        values[0] = 0
        weights[0] = 0
        p = 0
        while i >= A:
            for j in range(1 << p):
                values[j + (1 << p)] = values[j] + V[i]
                weights[j + (1 << p)] = weights[j] + W[i]
            p += 1
            i >>= 1
        best = 0
        for n in range(1 << p):
            if weights[n] > lim:
                continue
            x = dp[i][lim - weights[n]] + values[n]
            best = max(best, x)
        return best

    Q = len(v)
    for i in range(Q):
        x = solve(v[i], L[i], values, weights, dp)
        print(x)

        
if sys.argv[-1] == 'ONLINE_JUDGE':
    from numba.pycc import CC
    cc = CC('my_module')
    cc.export('main', '(i4,i4[:],i4[:],i4[:],i4[:])')(main)
    cc.compile()
    exit()

from my_module import main

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2].copy(), query[1::2].copy()

main(N, V, W, v, L)

Submission status: Accepted

Solution code:
import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines


def main(N, V, W, v, L):
    def precompute(N, V, W):
        U = 10**5 + 10
        dp = np.zeros((1024, U), np.int32)
        for v in range(1, min(1024, N + 1)):
            p = v // 2
            dp[v] = dp[p]
            dp[v, W[v]:] = np.maximum(dp[v, W[v]:], dp[p, :-W[v]] + V[v])
            for i in range(1, U):
                dp[v][i] = max(dp[v][i], dp[v][i - 1])
        return dp

    dp = precompute(N, V, W)
    values = np.empty(1024, np.int32)
    weights = np.empty(1024, np.int32)

    def solve(i, lim, values, weights, dp):
        if i < 1024:
            return dp[i][lim]
        values[0] = 0
        weights[0] = 0
        p = 0
        while i >= 1024:
            for j in range(1 << p):
                values[j + (1 << p)] = values[j] + V[i]
                weights[j + (1 << p)] = weights[j] + W[i]
            p += 1
            i >>= 1
        best = 0
        for n in range(1 << p):
            if weights[n] > lim:
                continue
            x = dp[i][lim - weights[n]] + values[n]
            best = max(best, x)
        return best

    Q = len(v)
    for i in range(Q):
        x = solve(v[i], L[i], values, weights, dp)
        print(x)

        
if sys.argv[-1] == 'ONLINE_JUDGE':
    from numba.pycc import CC
    cc = CC('my_module')
    cc.export('main', '(i4,i4[::1],i4[::1],i4[::1],i4[::1])')(main)
    cc.compile()
    exit()

from my_module import main

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2].copy(), query[1::2].copy()

main(N, V, W, v, L)

Submission status: Accepted

Solution code:
import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines


def main(N, V, W, v, L):
    def precompute(N, V, W):
        U = 10**5 + 10
        dp = np.zeros((1024, U), np.int32)
        for v in range(1, min(1024, N + 1)):
            p = v // 2
            dp[v] = dp[p]
            dp[v, W[v]:] = np.maximum(dp[v, W[v]:], dp[p, :-W[v]] + V[v])
            for i in range(1, U):
                dp[v][i] = max(dp[v][i], dp[v][i - 1])
        return dp

    dp = precompute(N, V, W)
    values = np.empty(1024, np.int32)
    weights = np.empty(1024, np.int32)

    def solve(i, lim, values, weights, dp):
        if i < 1024:
            return dp[i][lim]
        values[0] = 0
        weights[0] = 0
        p = 0
        while i >= 1024:
            for j in range(1 << p):
                values[j + (1 << p)] = values[j] + V[i]
                weights[j + (1 << p)] = weights[j] + W[i]
            p += 1
            i >>= 1
        best = 0
        for n in range(1 << p):
            if weights[n] > lim:
                continue
            x = dp[i][lim - weights[n]] + values[n]
            best = max(best, x)
        return best

    Q = len(v)
    for i in range(Q):
        x = solve(v[i], L[i], values, weights, dp)
        print(x)

        
if sys.argv[-1] == 'ONLINE_JUDGE':
    from numba.pycc import CC
    cc = CC('my_module')
    cc.export('main', '(i4,i4[:],i4[:],i4[:],i4[:])')(main)
    cc.compile()
    exit()

from my_module import main

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2], query[1::2]

main(N, V, W, v, L)

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline

N = int(input())
LIMIT = min(N,4195)

V = [0] * N
W = [0] * N
for i in range(N):
    nV, nW = map(int, input().split())
    V[i] = nV
    W[i] = nW

pre = [[] for i in range(LIMIT)]

for i in range(LIMIT):
    if i == 0:
        pre[i] = [(0,0), (W[i], V[i])]
        continue

    curr = pre[i]
    prev = pre[(i - 1)//2]
    nV, nW = V[i], W[i]
    
    size = len(prev)

    left = 0
    right = 0
    while left < size or right < size:
        if left == size or prev[left][0] > prev[right][0] + nW or (prev[left][0] == prev[right][0] + nW and prev[left][1] < prev[right][1] + nV):
            if len(curr) == 0 or prev[right][1] + nV > curr[-1][1]:
                curr.append((prev[right][0] + nW, prev[right][1] + nV))
            right += 1
        else:
            if len(curr) == 0 or prev[left][1] > curr[-1][1]:
                curr.append(prev[left])
            left += 1
            
Q = int(input())
out = [0] * Q
for t in range(Q):
    vert, L = map(int, input().split())
    vert -= 1

    stack = []
    while vert >= LIMIT:
        stack.append((V[vert], W[vert]))
        vert = (vert - 1) // 2
        
    prev = pre[vert]
    best = 0
    
    for i in range(1 << len(stack)):
        sV = 0
        sW = 0
        red = i
        for nV, nW in stack:
            if red & 1:
                sV += nV
                sW += nW
            red >>= 1

        limit = L - sW
        if limit < 0:
            continue
        
        lo = -1
        hi = len(prev)
        while hi - lo > 1:
            test = (hi + lo) // 2
            if prev[test][0] <= limit:
                lo = test
            else:
                hi = test
                
        if lo >= 0:
            new = prev[lo][1] + sV
            best = max(best, new)
        
    out[t] = best

print('\n'.join(map(str,out)))

Submission status: Accepted

Solution code:
import sys
import numpy as np
from numba import njit

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

# ノード、重さ→価値
@njit('(i4,i4[:],i4[:])', cache=True)
def precompute(N, V, W):
    U = 10**5 + 10
    dp = np.zeros((1024, U), np.int32)
    for v in range(1, min(1024, N + 1)):
        p = v // 2
        dp[v] = dp[p]
        dp[v, W[v]:] = np.maximum(dp[v, W[v]:], dp[p, :-W[v]] + V[v])
        for i in range(1, U):
            dp[v][i] = max(dp[v][i], dp[v][i - 1])
    return dp

@njit('(i4,i4[:],i4[:],i4[:],i4[:])', cache=True)
def main(N, V, W, v, L):
    dp = precompute(N, V, W)
    values = np.empty(1024, np.int32)
    weights = np.empty(1024, np.int32)

    def solve(i, lim, values, weights, dp):
        if i < 1024:
            return dp[i][lim]
        values[0] = 0
        weights[0] = 0
        p = 0
        while i >= 1024:
            for j in range(1 << p):
                values[j + (1 << p)] = values[j] + V[i]
                weights[j + (1 << p)] = weights[j] + W[i]
            p += 1
            i >>= 1
        best = 0
        for n in range(1 << p):
            if weights[n] > lim:
                continue
            x = dp[i][lim - weights[n]] + values[n]
            best = max(best, x)
        return best

    Q = len(v)
    for i in range(Q):
        x = solve(v[i], L[i], values, weights, dp)
        print(x)

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2], query[1::2]

main(N, V, W, v, L)

Submission status: Runtime Error

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    def dp_all(lis, l):
        res = [(0,0)]
        for v,w in lis:
            res += [(sv+v,sw+w) for (sv,sw) in res if sw+w <= l]
        return max(res)[0]

    def array(lis):
        res = [(0,0)]
        for v,w in lis:
            res += [(sw+w,sv+v) for (sw,sv) in res]
        res.sort(key = lambda x:(x[0],-x[1]))
        sw = []
        sv = []
        maxv = 0
        for i in range(len(res)):
            w,v = res[i]
            if v < maxv:
                continue
            sv.append(v)
            sw.append(w)
            maxv = v
        return sw, sv

    def dp(lis, res_sw, res_sv, l):
        liss = [(0,0)]
        for v,w in lis:
            liss += [(sv+v,sw+w) for (sv,sw) in liss if sw+w <= l]
        ans = 0
        for sv,sw in liss:
            j = bisect.bisect_right(res_sw, l-sw)-1
            s = sv+res_sv[j]
            if ans < s:
                ans = s
        return ans

    n = I()
    g = [None]*(n+1)
    for i in range(1,n+1):
        v,w = LI()
        g[i] = (v,w)
    q = I()
    m = n.bit_length()>>1
    B = 1<<m
    mem_sw = [None]*B
    mem_sv = [None]*B
    for _ in range(q):
        x,l = LI()
        lis = []
        bit = x
        while x:
            lis.append(g[x])
            x >>= 1
        h = len(lis)
        if h < m:
            print(dp_all(lis,l))
        else:
            bit = (bit-(bit&(B-1)))>>m
            if mem_sw[bit] is None:
                mem_sw[bit],mem_sv[bit] = array(lis[-m:])
            print(dp(lis[:-m], mem_sw[bit], mem_sv[bit], l))

    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Runtime Error

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    def dp_all(lis, l):
        res = 0
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
                    if sw > l:
                        break
            else:
                if res < sv:
                    res = sv
        return res

    def array(lis):
        res = defaultdict(lambda : 0)
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
            res[sw] = max(res[sw], sv)
        res = list(res.items())
        res.sort()
        sw = []
        sv = []
        maxv = 0
        for i in range(len(res)):
            w,v = res[i]
            if v < maxv:
                continue
            sv.append(v)
            sw.append(w)
            maxv = v
        return sw, sv

    def dp(lis, res_sw, res_sv, l):
        ret = 0
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
                    if sw > l:
                        break
            else:
                j = bisect.bisect_left(res_sw, l-sw+1)-1
                if 0 <= j < len(res_sv):
                    s = sv+res_sv[j]
                    if ret < s:
                        ret = s
        return ret

    n = I()
    g = [None]*(n+1)
    for i in range(1,n+1):
        v,w = LI()
        g[i] = (v,w)
    q = I()
    m = n.bit_length()>>1
    B = 1<<m
    mem_sw = [None]*B
    mem_sv = [None]*B
    for _ in range(q):
        x,l = LI()
        lis = []
        bit = x
        while x:
            lis.append(g[x])
            x >>= 1
        h = len(lis)
        if h < m:
            print(dp_all(lis,l))
        else:
            bit = (bit-(bit&(B-1)))>>m
            if mem_sw[bit] is None:
                mem_sw[bit],mem_sv[bit] = array(lis[-m:])
            print(dp(lis[:-m], mem_sw[bit], mem_sv[bit], l))

    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Runtime Error

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    def dp_all(lis, l):
        res = 0
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
                    if sw > l:
                        break
            else:
                if res < sv:
                    res = sv
        return res

    def array(lis):
        res = defaultdict(lambda : 0)
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
            res[sw] = max(res[sw], sv)
        res = list(res.items())
        res.sort()
        sw = []
        sv = []
        maxv = 0
        for i in range(len(res)):
            w,v = res[i]
            if v < maxv:
                continue
            sv.append(v)
            sw.append(w)
            maxv = v
        return sw, sv

    def dp(lis, res_sw, res_sv, l):
        ret = 0
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
                    if sw > l:
                        break
            else:
                j = bisect.bisect_left(res_sw, l-sw+1)-1
                s = sv+res_sv[j]
                if ret < s:
                    ret = s
        return ret

    n = I()
    g = [None]*(n+1)
    for i in range(1,n+1):
        v,w = LI()
        g[i] = (v,w)
    q = I()
    m = n.bit_length()>>1
    B = 1<<m
    mem_sw = [None]*B
    mem_sv = [None]*B
    for _ in range(q):
        x,l = LI()
        lis = []
        bit = x
        while x:
            lis.append(g[x])
            x >>= 1
        h = len(lis)
        if h < m:
            print(dp_all(lis,l))
        else:
            bit = (bit-(bit&(B-1)))>>m
            if mem_sw[bit] is None:
                mem_sw[bit],mem_sv[bit] = array(lis[-m:])
            print(dp(lis[:-m], mem_sw[bit], mem_sv[bit], l))

    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Runtime Error

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    def dp_all(lis, l):
        res = 0
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
                    if sw > l:
                        break
            else:
                if res < sv:
                    res = sv
        return res

    def array(lis):
        res = defaultdict(lambda : 0)
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
            res[sw] = max(res[sw], sv)
        res = list(res.items())
        res.sort()
        sw = []
        sv = []
        maxv = 0
        for i in range(len(res)):
            w,v = res[i]
            if v < maxv:
                continue
            sv.append(v)
            sw.append(w)
            maxv = v
        return sw, sv

    def dp(lis, res_sw, res_sv, l):
        ret = 0
        for b in range(1<<len(lis)):
            sv = 0
            sw = 0
            for i,(v,w) in enumerate(lis):
                if (b>>i)&1:
                    sv += v
                    sw += w
                    if sw > l:
                        break
            else:
                j = bisect.bisect_right(res_sw, l-sw) - 1
                s = sv+res_sv[j]
                if ret < s:
                    ret = s
        return ret

    n = I()
    g = [None]*(n+1)
    for i in range(1,n+1):
        v,w = LI()
        g[i] = (v,w)
    q = I()
    m = n.bit_length()>>1
    B = 1<<m
    mem_sw = [None]*B
    mem_sv = [None]*B
    for _ in range(q):
        x,l = LI()
        lis = []
        bit = x
        while x:
            lis.append(g[x])
            x >>= 1
        h = len(lis)
        if h < m:
            print(dp_all(lis,l))
        else:
            bit = (bit-(bit&(B-1)))>>m
            if mem_sw[bit] is None:
                mem_sw[bit],mem_sv[bit] = array(lis[-m:])
            print(dp(lis[:-m], mem_sw[bit], mem_sv[bit], l))

    return

#Solve
if __name__ == "__main__":
    solve()