Problem:


Score : 100 points

Problem Statement

There are N flowers arranged in a row.
For each i (1 \leq i \leq N), the height and the beauty of the i-th flower from the left is h_i and a_i, respectively.
Here, h_1, h_2, \ldots, h_N are all distinct.

Taro is pulling out some flowers so that the following condition is met:

The heights of the remaining flowers are monotonically increasing from left to right.

Find the maximum possible sum of the beauties of the remaining flowers.

Constraints

All values in input are integers.

1 \leq N \leq 2 × 10^5

1 \leq h_i \leq N

h_1, h_2, \ldots, h_N are all distinct.

1 \leq a_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
h_1 h_2 \ldots h_N
a_1 a_2 \ldots a_N

Output

Print the maximum possible sum of the beauties of the remaining flowers.

Sample Input 1

4
3 1 4 2
10 20 30 40

Sample Output 1

60

We should keep the second and fourth flowers from the left.
Then, the heights would be 1, 2 from left to right, which is monotonically increasing, and the sum of the beauties would be 20 + 40 = 60.

Sample Input 2

1
1
10

Sample Output 2

10

The condition is met already at the beginning.

Sample Input 3

5
1 2 3 4 5
1000000000 1000000000 1000000000 1000000000 1000000000

Sample Output 3

5000000000

The answer may not fit into a 32-bit integer type.

Sample Input 4

9
4 2 5 8 3 6 1 7 9
6 8 8 4 6 3 5 7 5

Sample Output 4

31

We should keep the second, third, sixth, eighth and ninth flowers from the left.



Sample input:
4
3 1 4 2
10 20 30 40


Sample output:
60

Submission status: Wrong Answer

Solution code:
n = int(input())
h = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]


class SegmentTree:
    def __init__(self, a, func=max, one=-10 ** 18):
        self.logn = (len(a) - 1).bit_length()
        self.n = 1 << self.logn
        self.func = func
        self.one = one

        self.b = [self.one] * (2 * self.n - 1)
        for i, j in enumerate(a):
            self.b[i + self.n - 1] = j
        for i in reversed(range(self.n - 1)):
            self.b[i] = self.func(self.b[i * 2 + 1], self.b[i * 2 + 2])

    def get_item(self, i):
        return self.b[i + self.n - 1]

    def update(self, index, x):
        i = index + self.n - 1
        self.b[i] = x
        while i != 0:
            i = (i - 1) // 2
            self.b[i] = self.func(self.b[i * 2 + 1], self.b[i * 2 + 2])

    def update_func(self, index, x):
        i = index + self.n - 1
        self.b[i] = self.func(self.b[i], x)
        while i != 0:
            i = (i - 1) // 2
            self.b[i] = self.func(self.b[i * 2 + 1], self.b[i * 2 + 2])

    def get_segment(self, l, r):
        l += self.n
        r += self.n
        s = self.one
        t = self.one
        while l < r:
            if l & 1:
                s = self.func(s, self.b[l - 1])
                l += 1
            if r & 1:
                r -= 1
                s = self.func(self.b[r - 1], t)
            l >>= 1
            r >>= 1
        return self.func(s, t)


seg = SegmentTree([0]*(n+1))

for i in range(n):
    j = seg.get_segment(0, h[i] + 1)
    seg.update_func(h[i], j + a[i])
print(seg.get_segment(0, n+1))

Submission status: Wrong Answer

Solution code:
# -*- coding: utf-8 -*-

#############
# Libraries #
#############

import sys
input = sys.stdin.readline

import math
#from math import gcd
import bisect
import heapq
from collections import defaultdict
from collections import deque
from collections import Counter
from functools import lru_cache

#############
# Constants #
#############

MOD = 10**9+7
INF = float('inf')
AZ = "abcdefghijklmnopqrstuvwxyz"

#############
# Functions #
#############

######INPUT######
def I(): return int(input().strip())
def S(): return input().strip()
def IL(): return list(map(int,input().split()))
def SL(): return list(map(str,input().split()))
def ILs(n): return list(int(input()) for _ in range(n))
def SLs(n): return list(input().strip() for _ in range(n))
def ILL(n): return [list(map(int, input().split())) for _ in range(n)]
def SLL(n): return [list(map(str, input().split())) for _ in range(n)]

######OUTPUT######
def P(arg): print(arg); return
def Y(): print("Yes"); return
def N(): print("No"); return
def E(): exit()
def PE(arg): print(arg); exit()
def YE(): print("Yes"); exit()
def NE(): print("No"); exit()

#####Shorten#####
def DD(arg): return defaultdict(arg)

#####Inverse#####
def inv(n): return pow(n, MOD-2, MOD)

######Combination######
kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n): return kaijo_memo[n]
  if(len(kaijo_memo) == 0): kaijo_memo.append(1)
  while(len(kaijo_memo) <= n): kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n): return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0): gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n): gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if n == r: return 1
  if n < r or r < 0: return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret

######Factorization######
def factorization(n):
  arr = []
  temp = n
  for i in range(2, int(-(-n**0.5//1))+1):
    if temp%i==0:
      cnt=0
      while temp%i==0: 
        cnt+=1 
        temp //= i
      arr.append([i, cnt])
  if temp!=1: arr.append([temp, 1])
  if arr==[]: arr.append([n, 1])
  return arr

#####MakeDivisors######
def make_divisors(n):
  divisors = []
  for i in range(1, int(n**0.5)+1):
    if n % i == 0:
      divisors.append(i)
      if i != n // i: 
        divisors.append(n//i)
  return divisors

#####MakePrimes######
def make_primes(N):
  max = int(math.sqrt(N))
  seachList = [i for i in range(2,N+1)]
  primeNum = []
  while seachList[0] <= max:
    primeNum.append(seachList[0])
    tmp = seachList[0]
    seachList = [i for i in seachList if i % tmp != 0]
  primeNum.extend(seachList)
  return primeNum

#####GCD#####
def gcd(a, b):
    while b: a, b = b, a % b
    return a

#####LCM#####
def lcm(a, b):
    return a * b // gcd (a, b)

#####BitCount#####
def count_bit(n):
  count = 0
  while n:
    n &= n-1
    count += 1
  return count

#####ChangeBase#####
def base_10_to_n(X, n):
  if X//n: return base_10_to_n(X//n, n)+[X%n]
  return [X%n]

def base_n_to_10(X, n):
  return sum(int(str(X)[-i-1])*n**i for i in range(len(str(X))))

def base_10_to_n_without_0(X, n):
  X -= 1
  if X//n: return base_10_to_n_without_0(X//n, n)+[X%n]
  return [X%n]

#####IntLog#####
def int_log(n, a):
  count = 0
  while n>=a:
    n //= a
    count += 1
  return count

#############
# Main Code #
#############
class SegmentTree:
  def __init__(self, n, op, e):
    self.n = n
    self.op = op
    self.e = e
    self.size = 2 ** ((n - 1).bit_length())
    self.node = [self.e] * (2 * self.size)
 
  def build(self, array):
    for i in range(self.n):
      self.node[self.size + i] = array[i]
    for i in range(self.size - 1, 0, -1):
      self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1])
 
  def update(self, i, val):
    i += self.size
    self.node[i] = val
    while i > 1:
      i >>= 1
      self.node[i] = self.op(self.node[i << 1], self.node[(i << 1) + 1])
 
  def get(self, l, r):
    l, r = l + self.size, r + self.size
    res_l, res_r = self.e, self.e
    while l < r:
      if l & 1:
        res_l = self.op(res_l, self.node[l])
        l += 1
      if r & 1:
        r -= 1
        res_r = self.op(self.node[r], res_r) 
      l, r = l >> 1, r >> 1
    return self.op(res_l, res_r)

N = I()
H = IL()
A = IL()

ST = SegmentTree(2*10**5,max,0)
for i in range(N):
  h = H[i]
  a = A[i]
  ST.update(h,ST.get(0,h)+a)
  
print(ST.get(0,2*10**5))

Submission status: Wrong Answer

Solution code:
import sys

input = sys.stdin.buffer.readline

n = int(input())
H = list(map(int, input().split()))
A = list(map(int, input().split()))


class SegmentTree:
    ele = 0

    def func(self, a, b):
        return a + b

    # SEG木は1-index
    # Aに関しては0-index

    def __init__(self, n):  # Aは0-idx
        self.n = n
        self.num = 2 ** ((self.n - 1).bit_length())
        self.SEG = [self.ele] * (2 * self.num)

    def search(self, idx):
        return self.SEG[idx + self.num]

    def initialize(self, A):
        for i in range(self.n):
            self.SEG[i + self.num] = A[i]
        for i in range(self.num - 1, 0, -1):
            self.SEG[i] = self.func(self.SEG[2 * i], self.SEG[2 * i + 1])

    def update(self, idx, val):
        idx += self.num
        self.SEG[idx] = val
        idx //= 2
        while idx:
            self.SEG[idx] = self.func(self.SEG[2 * idx], self.SEG[2 * idx + 1])
            idx //= 2

    # def delay(self,):

    def query(self, left, right):
        # maspy式。開区間のママ処理する
        # left, rightで値を分けているのは交換法則不成立のときのため
        # 開区間→Rが奇数→右端が偶数→1ずらしてから計算
        # 　下から上への遷移は2で割る
        # juppy氏は閉区間に直していた
        resleft = self.ele
        resright = self.ele
        left += self.num
        right += self.num
        while right - left > 0:
            if left % 2 == 1:
                resleft = self.func(resleft, self.SEG[left])
                left += 1
            if right % 2 == 1:
                right -= 1
                resright = self.func(resright, self.SEG[right])
            left //= 2
            right //= 2
        return self.func(resleft, resright)


ST = SegmentTree(n)
ans = 0
for i in range(n):
    h = H[i] - 1
    a = A[i]
    ST.update(h, a)
    temp = ST.query(0, h+1) + a
    ans = max(temp, ans)
print(ans)

Submission status: Wrong Answer

Solution code:
import sys

input = sys.stdin.buffer.readline

n = int(input())
H = list(map(int, input().split()))
A = list(map(int, input().split()))

dp = [0] * (n)


class SegmentTree:
    ele = 0

    def func(self, a, b):
        return a + b

    # SEG木は1-index
    # Aに関しては0-index

    def __init__(self, n):  # Aは0-idx
        self.n = n
        self.num = 2 ** ((self.n - 1).bit_length())
        self.SEG = [self.ele] * (2 * self.num)

    def search(self, idx):
        return self.SEG[idx + self.num]

    def initialize(self, A):
        for i in range(self.n):
            self.SEG[i + self.num] = A[i]
        for i in range(self.num - 1, 0, -1):
            self.SEG[i] = self.func(self.SEG[2 * i], self.SEG[2 * i + 1])

    def update(self, idx, val):
        idx += self.num
        self.SEG[idx] = val
        idx //= 2
        while idx:
            self.SEG[idx] = self.func(self.SEG[2 * idx], self.SEG[2 * idx + 1])
            idx //= 2

    # def delay(self,):

    def query(self, left, right):
        # maspy式。開区間のママ処理する
        # left, rightで値を分けているのは交換法則不成立のときのため
        # 開区間→Rが奇数→右端が偶数→1ずらしてから計算
        # 　下から上への遷移は2で割る
        # juppy氏は閉区間に直していた
        resleft = self.ele
        resright = self.ele
        left += self.num
        right += self.num
        while right - left > 0:
            if left % 2 == 1:
                resleft = self.func(resleft, self.SEG[left])
                left += 1
            if right % 2 == 1:
                right -= 1
                resright = self.func(resright, self.SEG[right])
            left //= 2
            right //= 2
        return self.func(resleft, resright)


ST = SegmentTree(n)
ans = 0
for i in range(n):
    h = H[i] - 1
    a = A[i]
    ST.update(h, a)
    temp = ST.query(0, h) + a
    ans = max(temp, ans)
print(ans)

Submission status: Wrong Answer

Solution code:
n = int(input())
H = list(map(int, input().split()))
A = list(map(int, input().split()))

dp = [0] * (n)


def func(a, b):
    return a + b


class SegmentTree:
    ele = 0

    def func(self, a, b):
        return a + b

    # SEG木は1-index
    # Aに関しては0-index

    def __init__(self, n):  # Aは0-idx
        self.n = n
        self.num = 2 ** ((self.n - 1).bit_length())
        self.SEG = [self.ele] * (2 * self.num)

    def search(self, idx):
        return self.SEG[idx + self.num]

    def initialize(self, A):
        for i in range(self.n):
            self.SEG[i + self.num] = A[i]
        for i in range(self.num - 1, 0, -1):
            self.SEG[i] = self.func(self.SEG[2 * i], self.SEG[2 * i + 1])

    def update(self, idx, val):
        idx += self.num
        self.SEG[idx] = val
        idx //= 2
        while idx:
            self.SEG[idx] = self.func(self.SEG[2 * idx], self.SEG[2 * idx + 1])
            idx //= 2

    # def delay(self,):

    def query(self, left, right):
        # maspy式。開区間のママ処理する
        # left, rightで値を分けているのは交換法則不成立のときのため
        # 開区間→Rが奇数→右端が偶数→1ずらしてから計算
        # 　下から上への遷移は2で割る
        # juppy氏は閉区間に直していた
        resleft = self.ele
        resright = self.ele
        left += self.num
        right += self.num
        while right - left > 0:
            if left % 2 == 1:
                resleft = self.func(resleft, self.SEG[left])
                left += 1
            if right % 2 == 1:
                right -= 1
                resright = self.func(resright, self.SEG[right])
            left //= 2
            right //= 2
        return self.func(resleft, resright)


ST = SegmentTree(n)
ans = 0
for i in range(n):
    h = H[i] - 1
    a = A[i]
    ST.update(h, a)
    temp = ST.query(0, h) + a
    ans = max(temp, ans)
print(ans)

Submission status: Wrong Answer

Solution code:
n=int(input())
h=list(map(int,input().split()))
a=list(map(int,input().split()))

#####segfunc######
def segfunc(x,y):
    return max(x,y)

def init(init_val):
    #set_val
    for i in range(n):
        seg[i+num-1]=init_val[i]
    #built
    for i in range(num-2,-1,-1) :
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2])

def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = segfunc(seg[k*2+1],seg[k*2+2])

def query(p,q):
    if q<=p:
        return ide_ele
    p += num-1
    q += num-2
    res=ide_ele
    while q-p>1:
        if p&1 == 0:
            res = segfunc(res,seg[p])
        if q&1 == 1:
            res = segfunc(res,seg[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = segfunc(res,seg[p])
    else:
        res = segfunc(segfunc(res,seg[p]),seg[q])
    return res

#####単位元######
ide_ele =0

#num:n以上の最小の2のべき乗
num =2**(n).bit_length()
seg=[ide_ele]*2*num

dp=[0 for i in range(0,n)]
dp[0]=a[0]
update(h[0],dp[0])

for i in range(1,n):
    dp[i]=a[i]+query(0,h[i])
    if dp[i]>query(h[i],h[i]+1):
        update(h[i],dp[i])

print(dp[n-1])

Submission status: Wrong Answer

Solution code:
n = int(input())
h = list(map(int, input().split()))
a = list(map(int, input().split()))
dp = [0] * (n + 1)
bit = [0] * (n + 1)
for x, y in zip(h, a):
    a = x
    t = 0
    while a > 0:
        t = max(t, bit[a])
        a -= a & -a
    t += y
    dp[x] = t
    while x <= n:
        bit[x] = max(bit[x], t)
        x += x & -x
print(bit[-1])

Submission status: Wrong Answer

Solution code:
def main():
    import sys
    input=sys.stdin.buffer.readline
    n=int(input())
    dp=[0]*-~n
    for h,a in zip(map(int,input().split()),map(int,input().split())):
        i,s=h,0
        while i:
            t=dp[i]
            if t>s:s=t
            i-=i&-i
        s+=a
        i=h
        while i<=n:
            if s>dp[i]:dp[i]=s
            i+=i&-i
    print(dp[n])
main()

Submission status: Wrong Answer

Solution code:

import sys
input = sys.stdin.readline
#区間の管理は　[a, b)で管理していることに注意

# INT_MIN = -10 ** 18
# MAX_N = 4 * 10 ** 5
# MAX_N = 20


# def init(n_):
#     #簡単にするために2のべき乗に揃える
#     n = 1
#     while n <= n_:
#         n *= 2
#     return n

#初期化
N = int(input())
# n = 1
# while n <= N:
#     n *= 2

n = 262144
data = [0] * (2 * n - 1)

def update(k, a):
    k = k + n - 1
    # data[k] = a
    while k >= 0:
        data[k] = max(a, data[k])
        k = (k - 1) // 2
        # data[k] = max(data[2 * k + 1], data[2 * k + 2])

def query(a, b, k, l, r):
    if r <= a or b <= l:
        return 0
    elif a <= l and r <= b:
        return data[k]
    else:
        return max(query(a, b, 2 * k + 1, l, (l + r)//2), query(a, b, 2 * k + 2, (l + r)//2, r))

H = tuple(map(int, input().split()))
A = tuple(map(int, input().split()))

# ans = 0

dp = [A[0]] + [0] * (N - 1)
update(H[0] - 1, A[0])
for i in range(1, N):
    # h = int(input())
    # a = int(input())
    dp[i] = query(0, H[i] - 1, 0, 0, n) + A[i]
    # h = H[i]
    # a = A[i]
    # tmp = query(1, h + 1) #[1, h)での最大値
    # print (h, tmp)
    update(H[i] - 1, dp[i])
    # ans = max(ans, tmp + a)
    # print (data)

print (query(0, N - 1, 0, 0, n))

Submission status: Wrong Answer

Solution code:
class SegmentTreeMax:
    def __init__(self, a):
        self.padding =  -float('inf')
        
        n = len(a)
        self.N = 2 ** (n-1).bit_length()
        self.data = [self.padding]*(self.N-1) + a + [self.padding]*(self.N-n)
        for i in range(2*self.N-2, 0, -2):
            self.data[(i-1)//2] = max(self.data[i], self.data[i-1])
    
    def update(self, idx, x):
        idx = self.N - 1 + idx
        self.data[idx] = x
        while idx:
            idx = (idx-1) // 2
            self.data[idx] = max(self.data[2*idx+1], self.data[2*idx+2])
    
    def search(self, i, j):
        # [i, j)の区間の最小値を求める
        idx1 = self.N-1+i
        idx2 = self.N-1+j-1
        result = self.padding
        while idx1 + 1 < idx2:
            if idx1&1 == 0: # idx1が偶数
                result = max(result, self.data[idx1])
            if idx2&1 == 1: # idx2が奇数
                result = max(result, self.data[idx2])
                idx2 -= 1
            
            idx1 //= 2
            idx2 = (idx2 - 1)//2
        
        if idx1 == idx2:
            result = max(result, self.data[idx1])
        else: # idx1 + 1 == idx2
            result = max(result, self.data[idx1], self.data[idx2])
        
        return result


N = int(input())
H = list(map(int, input().split()))
A = list(map(int, input().split()))

dp = [0] * N
st = SegmentTreeMax(dp)

ans = 0
for h, a in zip(H, A):
  M = st.search(0, h-1)
  st.update(h-1, M + a)

print(st.search(0, N))

Submission status: Wrong Answer

Solution code:
class Bit:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
  
    def sum(self, i):
        s = 0
        while i > 0:
            s = max(s, self.tree[i])
            i -= i & -i
        return s
  
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] = x
            i += i & -i

N, = map(int, input().split())
Hs = map(int, input().split())
As = map(int, input().split())
 
bit = Bit(N)
for h, a in zip(Hs, As):
    a0 = bit.sum(h)
    bit.add(h, a0+a)
print(bit.sum(N))

Submission status: Wrong Answer

Solution code:
#!/usr/bin/env python3
import sys
INF = float("inf")


def solve(N: int, h: "List[int]", a: "List[int]"):
    dp = [0]*(N+1)
    for i in range(1, N+1):
        dp[i] = a[i-1]
        height = 0
        for j in range(i-1, 0, -1):
            if h[j-1] < height:
                break
            if h[j-1] < h[i-1]:
                dp[i] = max(dp[i], dp[j]+a[i-1])
                height = h[j-1]
    print(max(dp))
    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    h = [int(next(tokens)) for _ in range(N)]  # type: "List[int]"
    a = [int(next(tokens)) for _ in range(N)]  # type: "List[int]"
    solve(N, h, a)


if __name__ == '__main__':
    main()

Submission status: Wrong Answer

Solution code:
N = int(input())
H = [int(h) for h in input().split()]
A = [int(a) for a in input().split()]

#区間の最大値を求めるセグメント木
seg = [0]*(2*N-1)
#for i in range(2*N-2, N-2, -1):
#    seg[i] = A[i-N+1]
    
#for i in range(N-2, -1, -1):
#    seg[i] = max(seg[2*i+1], seg[2*i+2])
    
def update(k, x):
    k += N-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = max(seg[2*k+1], seg[2*k+2])
        
def query(p, q):
    p += N-1
    q += N-2
    res = 0
    while q-p > 1:
        if p&1 == 0:
            res = max(res, seg[p])
        if q&1 == 1:
            res = max(res, seg[q])
            q -= 1
        p //= 2
        q = (q-1)//2
    if p == q:
        res = max(res, seg[q])
    else:
        res = max(res, seg[p], seg[q])
    return res

dp = [0]*N
dp[0] = A[0]
update(H[0]-1, A[0])
for i in range(N-1):
    dp[i+1] = query(0, H[i+1])+A[i+1]
    update(H[i+1]-1, dp[i+1])
    
print(dp[-1])

Submission status: Wrong Answer

Solution code:
import bisect
def main():
    N = int(input())
    h = tuple(map(int, input().split()))
    d = {}
    for i, v in enumerate(h):
        d[v] = i
    a = tuple(map(int, input().split()))
    la = [0] * N
    la[0] = a[0]
    lh = [h[0]]
    for i in range(1, N):
        insert_index = bisect.bisect_left(lh, h[i])
        if insert_index == 0:
            la[i] = a[i]
        else:
            la[i] = max(la[d[lh[j]]] for j in range(insert_index)) + a[i]
        lh.insert(insert_index, h[i])
        print(la)
    return max(la)
print(main())

Submission status: Wrong Answer

Solution code:
n=int(input())
def f(x):
    s=0
    while x>0:
        s=max(s,t[x])
        x-=x&-x
    return s
def g(x,y):
    while x<n+1:
        t[x]=max(y,t[x])
        x+=x&-x
t=[0]*(n+1)
h=list(map(int,input().split()))
a=list(map(int,input().split()))
for i in range(n):
    g(h[i],f(h[i]-1)+a[i])
    print(t)
print(max(t))

Submission status: Wrong Answer

Solution code:
class segTree:
  inf = 0
  def __init__(self, num):
    self.N = 1
    while self.N < num:
      self.N *= 2
    self.T = [self.inf] * (2 * self.N - 1)
  def do(self, l, r):
    #最大値
    return max(l, r)
  def set(self, L):
    for i in range(len(L)):
      self.update(i, L[i])
  def update(self, x, v):
    k = x + self.N - 1
    self.T[k] = v
    while k > 0:
      k = (k - 1) // 2
      self.T[k] = self.do(self.T[2*k+1], self.T[2*k+2])
  def getV(self, l, r):
    return self.getVs(l, r, 0, 0, self.N - 1)
  def getVs(self, l, r, k, kl, kr):
    if l <= kl and r >= kr:
      return self.T[k]
    t = (kl + kr) // 2
    if l > t:
      return self.getVs(l, r, 2 * k + 2, t + 1,kr)
    if r < t + 1:
      return self.getVs(l, r , 2 * k + 1, kl, t)
    return self.do(self.getVs(l, r , 2 * k + 1, kl,t),
              self.getVs(l, r , 2 * k + 2, t + 1, kr))

import copy
N = int(input())
h = list(map(int, input().split()))
a = list(map(int, input().split()))

D = segTree(N)
x = copy.deepcopy(h)
x.sort()
R = {}
for i in range(N):
  R[x[i]] = i

DP = [0] * N
for i in range(N):
  DP[i] = D.getV(0, R[h[i]]) + a[i]
  D.update(R[h[i]], DP[i])

print(DP[-1])

Submission status: Wrong Answer

Solution code:
def get(i):
    mx = 0
    while i > 0:
        if bit[i] > mx:
            mx = bit[i]
        i -= i & -i
    return mx


def update(i, x):
    while i < n + 1:
        if x > bit[i]:
            bit[i] = x
        i += i & -i


n = int(input())
hs = list(map(int, input().split()))
a_s = list(map(int, input().split()))

bit = [0] * (n + 1)
for h, a in zip(hs, a_s):
    update(h,get(h-1)+a)
print(bit[-1])

Submission status: Wrong Answer

Solution code:
def solve(n, hhh, aaa):
    n2 = 1 << n.bit_length()
    offset = n2 - 1
    data = [0] * ((n2 << 1) - 1)

    def update(k, x):
        i = k + offset
        data[i] = max(data[i], x)
        while i:
            i = (i - 1) // 2
            data[i] = max(data[i], x)

    def get_max(k):
        i = k + offset
        ret = data[i]
        while i:
            i = (i - 1) // 2
            if i % 2 == 0:
                ret = max(ret, data[i - 1])
        return ret

    srt = sorted((h, i) for i, h in enumerate(hhh))
    for h, i in srt:
        update(i, get_max(i) + aaa[i])

    return get_max(offset)


n = int(input())
hhh = list(map(int, input().split()))
aaa = list(map(int, input().split()))
print(solve(n, hhh, aaa))

Submission status: Wrong Answer

Solution code:
class Segmenttree_max():
    def __init__(self, number):
        n = 1
        while n < number:
            n *= 2
        self.n = n
        self.list = [0] * (2 * n - 1)

    def add(self, i, x):  # 0indexed ith add x
        i += self.n - 1
        self.list[i] = x
        while i > 0:
            i = (i - 1) // 2
            self.list[i] = max(self.list[2 * i + 1], self.list[2 * i + 2])

    def search(self, a, b, k, l, r):  # call as search(a,b,0,0,self.n) maximum in [a,b)
        if r <= a or b <= l:
            return 0
        elif a <= l and r <= b:
            return self.list[k]
        else:
            vl = self.search(a, b, 2 * k + 1, l, (l + r) // 2)
            vr = self.search(a, b, 2 * k + 2, (l + r) // 2, r)
            return max(vl, vr)


N = int(input())
H = [int(i) for i in input().split()]
A = [int(i) for i in input().split()]
tree = Segmenttree_max(N)
dp = [0] * (N + 1)
for i in range(1, N + 1):
    dp[i] = tree.search(0, H[i - 1] - 1, 0, 0, tree.n) + A[i - 1]
    tree.add(H[i - 1] - 1, dp[i])
print(dp[N])

Submission status: Time Limit Exceeded

Solution code:
from collections import defaultdict

N = int(input())
H = list(map(int, input().split()))
A = list(map(int, input().split()))

DP = defaultdict(int)

for h, a in zip(H, A):
    m = 0
    for key, value in DP.items():
        if key < h:
            m = max(m, value)
    DP[h] = max(DP[h], m + a)

print(max(DP.values()))

Submission status: Time Limit Exceeded

Solution code:
n= int(input())
h=[int(X) for X in input().split()]
a=[int(x) for x in input().split()]
dp = a[:]

for i in range(n):
    for j in range(i):
        if h[i]>h[j] and dp[i]<dp[j]+a[i]:
            dp[i]=dp[j]+a[i]
print(max(dp))

Submission status: Time Limit Exceeded

Solution code:
# EDPC Q - Flowers
# 重み付きのLISと言って良いような問題
# これは、LISのdpを少し改造すれば解ける

## test data
# 4
# 3 1 4 2
# 10 20 30 40
## ans=60

import bisect

class SegTree:
	"""
	1-indexed
	"""
	def __init__(self,size,func,init_val,undef):
		self.specSize = size
		self.datSize = 1
		self.compareFunc = func		# suppose to min or max
		self.INIT_VAL = init_val	# 0 etc
		self.UNDEFINED_VAL = undef	# 1e18 -1e18 etc
		# num:size以上の最小の2のべき乗
		# self.datSize = 2**(size-1).bit_length()
		self.datSize = 2**size.bit_length()
		# while self.datSize < size: self.datSize *= 2

		# the tree is implemented by sequencial list
		# (1-indexed, 0 is not use.)
		self.datTree = [self.INIT_VAL for _ in range(2*self.datSize+1)]

	def update(self, i, val ):
		"""
		i: index(1-ordered)
		"""
		# i -= 1	# 1-orderで指定され、内部では0-Order想定?
		# i += (self.datSize - 1)
		i += self.datSize
		# print("upd",i,val)
		self.datTree[i] = val
		while 1 < i:
			# i = (i-1) >> 1	# (i-1)//2
			i >>= 1
			self.datTree[i] = self.compareFunc( self.datTree[i<<1|0], self.datTree[i<<1|1] )
			# print("upd",i,self.datTree[i])
			# self.printTree()

	def query(self,a,b):
		return self.query_(a,b,1,0,self.datSize)

	def query_(self,a,b,i,l,r):
		""" get minimun/maximum value of range[a,b)
		all 1-indexed
		i is the root vertex of search 
		l,r is range of the root vertex(not use)
		"""
		ret = self.UNDEFINED_VAL

		a += self.datSize
		b += self.datSize
		while a < b:
			if b & 1:
				b -= 1
				ret = self.compareFunc(ret, self.datTree[b])

			if a & 1:
				ret = self.compareFunc(ret, self.datTree[a])
				a += 1

			a >>= 1; b >>= 1

		return ret
	def query_recursive(self,a,b,i,l,r):
		""" get minimun/maximum value of range[a,b)
		all 1-indexed
		i is the root vertex of search 
		l,r is range of the root vertex
		"""
		if r <= a or b <= l:
			# (a,b) and (l,r) is not intersected
			return self.UNDEFINED_VAL

		if a <= l and r <= b:
			# i is index required
			return self.datTree[i]
		else:
			# search children
			m = (l+r) >> 1 #(l+r) // 2
			# vl = self.query_(a, b, i*2 + 1, l, m )
			# vr = self.query_(a, b, i*2 + 2, m, r )
			vl = self.query_(a, b, (i>>1) + 1, l, m )
			vr = self.query_(a, b, (i>>1) + 2, m, r )
			return self.compareFunc(vl,vr)

	def printTree(self):
		print(self.datTree)
		# print("root")



def LongestIncreaseSeaquence(H,A):
	# === Coordinate compression ===
	# unique and sort asc
	N = len(H)
	# sortedA = sorted(list(set(A)))
	lis = 0

	# === Range Maximum Query ===
	# ここでは、各要素iに、最後の値がiの時のLISを登録
	tree = SegTree(N,max,0,-1e18)
	for n in range(N):

		# i=bisect.bisect_left(sortedA,A[n])

		maxValOfCurrentRange = tree.query(0,H[n])
		# valOfNext = tree.query(H[n],H[n]+1)

		# # i+=1

		# if valOfNext < maxValOfCurrentRange + A[n]:
		# print( H[n], maxValOfCurrentRange + A[n] )
		# tree.debugPrint()
		tree.update( H[n], maxValOfCurrentRange + A[n] )

	# tree.printTree()
	lis = tree.query(0,N+1)
	return lis


def main():
	N = int(input())
	# 高さは、N以下で全部違うらしい
	H = list(map(int, input().split()))
	A = list(map(int, input().split()))
	# A = [ int(input()) for _ in range(N)]
	print(LongestIncreaseSeaquence(H,A))



if __name__ == "__main__":
	main()