Buggy python submission (verdict: Runtime Error):
class BITmax:
    def __init__(self, N, init=0):
        self.init = init
        self.tree = [self.init] * (N+1)
    
    def set(self, x, value):
        while x < N + 1:
            old = self.tree[x]
            if value <= old:
                break
            self.tree[x] = value
            x += x & -x
    
    def find_max_to(self, x):
        result = self.init
        while x > 0:
            result = max(result, self.tree[x])
            x -= x & -x
        return result

def main():
    N = int(input())
    dpt = BITmax(N)

    h_list = list(map(int, input().split()))
    b_list = list(map(int, input().split()))

    for h, b in zip(h_list, b_list):
        dpt.set(h, dpt.find_max_to(h-1) + b)

    print(max(dpt.tree))

if __name__ == '__main__':
    main()


Fixed submission:
class BITmax:
    def __init__(self, N, init=0):
        self.init = init
        self.tree = [self.init] * (N+1)
    
    def set(self, x, value):
        while x < N + 1:
            old = self.tree[x]
            if value <= old:
                break
            self.tree[x] = value
            x += x & -x
    
    def find_max_to(self, x):
        result = self.init
        while x > 0:
            result = max(result, self.tree[x])
            x -= x & -x
        return result

N = int(input())
dpt = BITmax(N)

h_list = list(map(int, input().split()))
b_list = list(map(int, input().split()))

for h, b in zip(h_list, b_list):
    dpt.set(h, dpt.find_max_to(h-1) + b)

print(max(dpt.tree))

Buggy python submission (verdict: Time Limit Exceeded):
import math
import sys
input = sys.stdin.readline

# セグメント木のクラス
# 後日遅延評価なども取り入れていきたいが、とりあえず
# 基本的なところだけを分かりやすい形で組んでみたもの
# length:データ部の長さ depth:構造全体の深さ
# offset:上位構造の長さ tree:全体リスト
 
class Segment_Tree:
    # コンストラクタ。リストもしくは要素数にて初期化。
    # デフォルトでは最小値を求めるが、op(operation=演算内容、デフォルトは最小値)、
    # ie(identity element単位元)を指定することも可能(f.e: op=operator.add, ie=0)
    def __init__(self, arg1, op=lambda x, y:x if x < y else y, ie=math.inf):
        self.op = op
        self.ie = ie
 
        if type(arg1) == int:
            default_list = []
            self.length = arg1
        else:
            default_list = list(arg1)
            self.length = len(arg1)
 
        # 全体の深さ、上位構造分のオフセットを求める
        self.depth = 0
        self.offset = 1
        while self.offset < self.length:
            self.depth += 1
            self.offset *= 2
 
        # 木の初期化。構造は1-indexedで使用していくことにする
        self.tree = [self.ie] * (self.offset * 2)
        if default_list:
            self.tree[self.offset:self.offset+self.length] = default_list
            self.refresh()
 
    # 全体の再計算(愚直に……)
    def refresh(self):
        for idx in range(self.offset - 1, 0, -1):
            self.tree[idx] = self.op(self.tree[idx*2], self.tree[idx*2+1])
 
    # 値のセット、及び関連する部分の再計算
    def set(self, idx, value):
        idx = idx + self.offset
        self.tree[idx] = value
        while idx > 1:
            idx //= 2
            old = self.tree[idx]
            new = self.op(self.tree[idx*2], self.tree[idx*2+1])
            # 変更がなくなれば打ち切り
            if old == new:
                break
            else:
                self.tree[idx] = new
        
    # 半開区間[left, right)における欲しい値(アレっすよ、アレ)を求める
    def find(self, left, right):
        # 区間がおかしなときは、エラー代わりに単位元とかでも返しておく
        if left >= right:
            return self.ie
        
        # 左端と右端から上位を見ていく
        result = self.ie
        left = left + self.offset
        right = right + self.offset - 1
 
        # 左端と右端が重なるとこまで演算
        while left <= right:
            # 左端は、自身が親の右側の子の時(=ノード番号が奇数のとき)にだけ演算する
            if left & 1:
                result = self.op(result, self.tree[left])
            # 一段上に移動
            left = (left + 1) // 2
 
            # 右端は、自身が親の左側の(以下略
            if not right & 1:
                result = self.op(result, self.tree[right])
            right = (right - 1) // 2
       
        return result
    
    # データ領域の値をindexに応じて返す
    def get(self, x):
        return self.tree[x+self.offset]
 
    # 全領域を対象にした計算値を返す
    def find_all(self):
        return self.tree[1]
    
    # 保持している値全体を返す（デバッグ用？）
    def show_tree(self):
        print(self.tree)
 
def main():
    N = int(input())
    h_list = list(map(int, input().split()))
    b_list = list(map(int, input().split()))
 
    dpt = Segment_Tree(N+1, op=lambda x,y:x if x>y else y, ie=0)
 
    for height, beauty in zip(h_list, b_list):
        max_to_left = dpt.find(0, height)
        dpt.set(height, max(dpt.get(height), max_to_left + beauty))
    
    print(dpt.find_all())
 
if __name__ == '__main__':
    main()

Fixed submission:
class BITmax:
    def __init__(self, N, init=0):
        self.init = init
        self.tree = [self.init] * (N+1)
    
    def set(self, x, value):
        while x < N + 1:
            old = self.tree[x]
            if value <= old:
                break
            self.tree[x] = value
            x += x & -x
    
    def find_max_to(self, x):
        result = self.init
        while x > 0:
            result = max(result, self.tree[x])
            x -= x & -x
        return result

N = int(input())
dpt = BITmax(N)

h_list = list(map(int, input().split()))
b_list = list(map(int, input().split()))

for h, b in zip(h_list, b_list):
    dpt.set(h, dpt.find_max_to(h-1) + b)

print(max(dpt.tree))

Buggy python submission (verdict: Time Limit Exceeded):
# 演算内容、単位元の必要に応じて(コンストラクタ参照)
import math

# セグメント木のクラス
# 後日遅延評価なども取り入れていきたいが、とりあえず
# 基本的なところだけを分かりやすい形で組んでみたもの
# length:データ部の長さ depth:構造全体の深さ
# offset:上位構造の長さ tree:全体リスト

class Segment_Tree:
    # コンストラクタ。リストもしくは要素数にて初期化。
    # デフォルトでは最小値を求めるが、op(operation=演算内容、デフォルトは最小値)、
    # ie(identity element単位元)を指定することも可能(f.e: op=operator.add, ie=0)
    def __init__(self, arg1, op=lambda x, y:x if x < y else y, ie=math.inf):
        self.op = op
        self.ie = ie

        if type(arg1) == int:
            default_list = []
            self.length = arg1
        else:
            default_list = list(arg1)
            self.length = len(arg1)

        # 全体の深さ、上位構造分のオフセットを求める
        self.depth = 0
        self.offset = 1
        while self.offset < self.length:
            self.depth += 1
            self.offset *= 2

        # 木の初期化。構造は1-indexedで使用していくことにする
        self.tree = [self.ie] * (self.offset * 2)
        if default_list:
            self.tree[self.offset:self.offset+self.length] = default_list
            self.refresh()

    # 全体の再計算(愚直に……)
    def refresh(self):
        for idx in range(self.offset - 1, 0, -1):
            self.tree[idx] = self.op(self.tree[idx*2], self.tree[idx*2+1])

    # 値のセット、及び関連する部分の再計算
    def set(self, idx, value):
        idx = idx + self.offset
        self.tree[idx] = value
        while idx > 1:
            idx //= 2
            old = self.tree[idx]
            new = self.op(self.tree[idx*2], self.tree[idx*2+1])
            # 変更がなくなれば打ち切り
            if old == new:
                break
            else:
                self.tree[idx] = new
        
    # 半開区間[left, right)における欲しい値(アレっすよ、アレ)を求める
    def find(self, left, right):
        # 区間がおかしなときは、エラー代わりに単位元とかでも返しておく
        if left >= right:
            return self.ie
        
        # 左端と右端から上位を見ていく
        result = self.ie
        left = left + self.offset
        right = right + self.offset - 1

        # 左端と右端が重なるとこまで演算
        while left <= right:
            # 左端は、自身が親の右側の子の時(=ノード番号が奇数のとき)にだけ演算する
            if left & 1:
                result = self.op(result, self.tree[left])
            # 一段上に移動
            left = (left + 1) // 2

            # 右端は、自身が親の左側の(以下略
            if not right & 1:
                result = self.op(result, self.tree[right])
            right = (right - 1) // 2
       
        return result
    
    # データ領域の値をindexに応じて返す
    def get(self, x):
        return self.tree[x+self.offset]

    # 全領域を対象にした計算値を返す
    def find_all(self):
        return self.tree[1]
    
    # 保持している値全体を返す（デバッグ用？）
    def show_tree(self):
        print(self.tree)

def main():
    N = int(input())
    h_list = list(map(int, input().split()))
    b_list = list(map(int, input().split()))

    dpt = Segment_Tree(N+1, op=lambda x,y:x if x>y else y, ie=0)

    for height, beauty in zip(h_list, b_list):
        max_to_left = dpt.find(0, height)
        dpt.set(height, max(dpt.get(height), max_to_left + beauty))
    
    print(dpt.find_all())

if __name__ == '__main__':
    main()



Fixed submission:
class BITmax:
    def __init__(self, N, init=0):
        self.init = init
        self.tree = [self.init] * (N+1)
    
    def set(self, x, value):
        while x < N + 1:
            old = self.tree[x]
            if value <= old:
                break
            self.tree[x] = value
            x += x & -x
    
    def find_max_to(self, x):
        result = self.init
        while x > 0:
            result = max(result, self.tree[x])
            x -= x & -x
        return result

N = int(input())
dpt = BITmax(N)

h_list = list(map(int, input().split()))
b_list = list(map(int, input().split()))

for h, b in zip(h_list, b_list):
    dpt.set(h, dpt.find_max_to(h-1) + b)

print(max(dpt.tree))

Buggy python submission (verdict: Time Limit Exceeded):
# 演算内容、単位元の必要に応じて(コンストラクタ参照)
import math

# セグメント木のクラス
# 後日遅延評価なども取り入れていきたいが、とりあえず
# 基本的なところだけを分かりやすい形で組んでみたもの
# length:データ部の長さ depth:構造全体の深さ
# offset:上位構造の長さ tree:全体リスト

class Segment_Tree:
    # コンストラクタ。リストもしくは要素数にて初期化。
    # デフォルトでは最小値を求めるが、op(operation=演算内容、デフォルトは最小値)、
    # ie(identity element単位元)を指定することも可能(f.e: op=operator.add, ie=0)
    def __init__(self, arg1, op=lambda x, y:x if x < y else y, ie=math.inf):
        self.op = op
        self.ie = ie

        if type(arg1) == int:
            default_list = []
            self.length = arg1
        else:
            default_list = list(arg1)
            self.length = len(arg1)

        # 全体の深さ、上位構造分のオフセットを求める
        self.depth = 0
        self.offset = 1
        while self.offset < self.length:
            self.depth += 1
            self.offset *= 2

        # 木の初期化。構造は1-indexedで使用していくことにする
        self.tree = [self.ie] * (self.offset * 2)
        if default_list:
            self.tree[self.offset:self.offset+self.length] = default_list
            self.refresh()

    # 全体の再計算(愚直に……)
    def refresh(self):
        for idx in range(self.offset - 1, 0, -1):
            self.tree[idx] = self.op(self.tree[idx*2], self.tree[idx*2+1])

    # 値のセット、及び関連する部分の再計算
    def set(self, idx, value):
        idx = idx + self.offset
        self.tree[idx] = value
        while idx > 1:
            idx //= 2
            self.tree[idx] = self.op(self.tree[idx*2], self.tree[idx*2+1])
        
    # 半開区間[left, right)における欲しい値(アレっすよ、アレ)を求める
    def find(self, left, right):
        # 区間がおかしなときは、エラー代わりに単位元とかでも返しておく
        if left >= right:
            return self.ie
        
        # 左端と右端から上位を見ていく
        result = self.ie
        left = left + self.offset
        right = right + self.offset - 1

        # 左端と右端が重なるとこまで演算
        while left <= right:
            # 左端は、自身が親の右側の子の時(=ノード番号が奇数のとき)にだけ演算する
            if left % 2 == 1:
                result = self.op(result, self.tree[left])
            # 一段上に移動
            left = (left + 1) // 2

            # 右端は、自身が親の左側の(以下略
            if right % 2 == 0:
                result = self.op(result, self.tree[right])
            right = (right - 1) // 2
       
        return result
    
    # データ領域の値をindexに応じて返す
    def get(self, x):
        return self.tree[x+self.offset]

    # 全領域を対象にした計算値を返す
    def find_all(self):
        return self.tree[1]
    
    # 保持している値全体を返す（デバッグ用？）
    def show_tree(self):
        print(self.tree)

def main():
    N = int(input())
    h_list = list(map(int, input().split()))
    b_list = list(map(int, input().split()))

    dpt = Segment_Tree(N+1, op=lambda x,y:x if x>y else y, ie=0)

    for height, beauty in zip(h_list, b_list):
        max_to_left = dpt.find(0, height)
        dpt.set(height, max(dpt.get(height), max_to_left + beauty))
    
    print(dpt.find_all())

if __name__ == '__main__':
    main()


Fixed submission:
class BITmax:
    def __init__(self, N, init=0):
        self.init = init
        self.tree = [self.init] * (N+1)
    
    def set(self, x, value):
        while x < N + 1:
            old = self.tree[x]
            if value <= old:
                break
            self.tree[x] = value
            x += x & -x
    
    def find_max_to(self, x):
        result = self.init
        while x > 0:
            result = max(result, self.tree[x])
            x -= x & -x
        return result

N = int(input())
dpt = BITmax(N)

h_list = list(map(int, input().split()))
b_list = list(map(int, input().split()))

for h, b in zip(h_list, b_list):
    dpt.set(h, dpt.find_max_to(h-1) + b)

print(max(dpt.tree))

Buggy python submission (verdict: Time Limit Exceeded):
# 演算内容、単位元の必要に応じて(コンストラクタ参照)
import math

# セグメント木のクラス
# 後日遅延評価なども取り入れていきたいが、とりあえず
# 基本的なところだけを分かりやすい形で組んでみたもの
# length:データ部の長さ depth:構造全体の深さ
# offset:上位構造の長さ tree:全体リスト

class Segment_Tree:
    # コンストラクタ。リストもしくは要素数にて初期化。
    # デフォルトでは最小値を求めるが、op(operation=演算内容、デフォルトは最小値)、
    # ie(identity element単位元)を指定することも可能(f.e: op=operator.add, ie=0)
    def __init__(self, arg1, op=lambda x, y:x if x < y else y, ie=math.inf):
        self.op = op
        self.ie = ie

        if type(arg1) == int:
            default_list = []
            self.length = arg1
        else:
            default_list = list(arg1)
            self.length = len(arg1)

        # 全体の深さ、上位構造分のオフセットを求める
        self.depth = 0
        self.offset = 1
        while self.offset < self.length:
            self.depth += 1
            self.offset *= 2

        # 木の初期化。構造は1-indexedで使用していくことにする
        self.tree = [self.ie] * (self.offset * 2)
        if default_list:
            self.tree[self.offset:self.offset+self.length] = default_list
            self.refresh()

    # 全体の再計算(愚直に……)
    def refresh(self):
        for idx in range(self.offset - 1, 0, -1):
            self.tree[idx] = self.op(self.tree[idx*2], self.tree[idx*2+1])

    # 値のセット、及び関連する部分の再計算
    def set(self, idx, value):
        idx = idx + self.offset
        self.tree[idx] = value
        while idx > 1:
            idx //= 2
            old = self.tree[idx]
            new = self.op(self.tree[idx*2], self.tree[idx*2+1])
            if old == new:
                break
            else:
                self.tree[idx] = new
        
    # 半開区間[left, right)における欲しい値(アレっすよ、アレ)を求める
    def find(self, left, right):
        # 区間がおかしなときは、エラー代わりに単位元とかでも返しておく
        if left >= right:
            return self.ie
        
        # 左端と右端から上位を見ていく
        result = self.ie
        left = left + self.offset
        right = right + self.offset - 1

        # 左端と右端が重なるとこまで演算
        while left <= right:
            # 左端は、自身が親の右側の子の時(=ノード番号が奇数のとき)にだけ演算する
            if left % 2 == 1:
                result = self.op(result, self.tree[left])
            # 一段上に移動
            left = (left + 1) // 2

            # 右端は、自身が親の左側の(以下略
            if right % 2 == 0:
                result = self.op(result, self.tree[right])
            right = (right - 1) // 2
       
        return result
    
    # データ領域の値をindexに応じて返す
    def get(self, x):
        return self.tree[x+self.offset]

    # 全領域を対象にした計算値を返す
    def find_all(self):
        return self.tree[1]
    
    # 保持している値全体を返す（デバッグ用？）
    def show_tree(self):
        print(self.tree)

def main():
    N = int(input())
    h_list = list(map(int, input().split()))
    b_list = list(map(int, input().split()))

    dpt = Segment_Tree(N+1, op=lambda x,y:x if x>y else y, ie=0)

    for height, beauty in zip(h_list, b_list):
        max_to_left = dpt.find(0, height)
        dpt.set(height, max(dpt.get(height), max_to_left + beauty))
    
    print(dpt.find_all())

if __name__ == '__main__':
    main()



Fixed submission:
class BITmax:
    def __init__(self, N, init=0):
        self.init = init
        self.tree = [self.init] * (N+1)
    
    def set(self, x, value):
        while x < N + 1:
            old = self.tree[x]
            if value <= old:
                break
            self.tree[x] = value
            x += x & -x
    
    def find_max_to(self, x):
        result = self.init
        while x > 0:
            result = max(result, self.tree[x])
            x -= x & -x
        return result

N = int(input())
dpt = BITmax(N)

h_list = list(map(int, input().split()))
b_list = list(map(int, input().split()))

for h, b in zip(h_list, b_list):
    dpt.set(h, dpt.find_max_to(h-1) + b)

print(max(dpt.tree))

Buggy python submission (verdict: Time Limit Exceeded):
# 演算内容、単位元の必要に応じて(コンストラクタ参照)
import math

# セグメント木のクラス
# 後日遅延評価なども取り入れていきたいが、とりあえず
# 基本的なところだけを分かりやすい形で組んでみたもの
# length:データ部の長さ depth:構造全体の深さ
# offset:上位構造の長さ tree:全体リスト

class Segment_Tree:
    # コンストラクタ。リストもしくは要素数にて初期化。
    # デフォルトでは最小値を求めるが、op(operation=演算内容、デフォルトは最小値)、
    # ie(identity element単位元)を指定することも可能(f.e: op=operator.add, ie=0)
    def __init__(self, arg1, op=lambda x, y:x if x < y else y, ie=math.inf):
        self.op = op
        self.ie = ie

        if type(arg1) == int:
            default_list = []
            self.length = arg1
        else:
            default_list = list(arg1)
            self.length = len(arg1)

        # 全体の深さ、上位構造分のオフセットを求める
        self.depth = 0
        self.offset = 1
        while self.offset < self.length:
            self.depth += 1
            self.offset *= 2

        # 木の初期化。構造は1-indexedで使用していくことにする
        self.tree = [self.ie] * (self.offset * 2)
        if default_list:
            self.tree[self.offset:self.offset+self.length] = default_list
            self.refresh()

    # 全体の再計算(愚直に……)
    def refresh(self):
        for idx in range(self.offset - 1, 0, -1):
            self.tree[idx] = self.op(self.tree[idx*2], self.tree[idx*2+1])

    # 値のセット、及び関連する部分の再計算
    def set(self, idx, value):
        idx = idx + self.offset
        self.tree[idx] = value
        while idx > 1:
            idx //= 2
            old = self.tree[idx]
            new = self.op(self.tree[idx*2], self.tree[idx*2+1])
            if old == new:
                break
            else:
                self.tree[idx] = new
        
    # 半開区間[left, right)における欲しい値(アレっすよ、アレ)を求める
    def find(self, left, right):
        # 区間がおかしなときは、エラー代わりに単位元でも返しておく
        if left >= right:
            return self.ie
        
        # 1(tree全体を含むもの)から探索開始。キューには探索対象の深さも一緒に入れておく
        result = self.ie
        queue = [(1, 0)]
        while len(queue) > 0:
            node, node_depth = queue.pop()

            # 対象ノードが受け持つ区間を求める
            width = 2 ** (self.depth - node_depth)
            idx_in_row = node - 2 ** (node_depth)
            node_left = width * idx_in_row
            node_right = node_left + width

            # 範囲外なら探索終了
            if node_right <= left or right <= node_left:
                continue

            # はみ出てたら子をキューに追加
            if node_left < left or right < node_right:
                queue.append((node * 2, node_depth + 1))
                queue.append((node * 2 + 1, node_depth + 1))
                continue

            # ここまで来たのならノードの情報は探索範囲に包含されている
            result = self.op(result, self.tree[node])
        
        return result
    
    def get(self, x):
        return self.tree[x+self.offset]

    def find_all(self):
        return self.tree[1]
    
    def show_tree(self):
        print(self.tree)


def main():
    N = int(input())
    dpt = Segment_Tree(N + 1, op=lambda x, y:x if x>y else y, ie=0)
    h_list = list(map(int, input().split()))
    a_list = list(map(int, input().split()))

    for height, beauty in zip(h_list, a_list):
        value = dpt.find(0, height) + beauty
        dpt.set(height, max(value, dpt.get(height)))
    
    print(dpt.find_all())

if __name__ == '__main__':
    main()


Fixed submission:
class BITmax:
    def __init__(self, N, init=0):
        self.init = init
        self.tree = [self.init] * (N+1)
    
    def set(self, x, value):
        while x < N + 1:
            old = self.tree[x]
            if value <= old:
                break
            self.tree[x] = value
            x += x & -x
    
    def find_max_to(self, x):
        result = self.init
        while x > 0:
            result = max(result, self.tree[x])
            x -= x & -x
        return result

N = int(input())
dpt = BITmax(N)

h_list = list(map(int, input().split()))
b_list = list(map(int, input().split()))

for h, b in zip(h_list, b_list):
    dpt.set(h, dpt.find_max_to(h-1) + b)

print(max(dpt.tree))