Problem:


Score : 600 points

Problem Statement

We have a tree with N vertices, whose i-th edge connects Vertex u_i and Vertex v_i.
Vertex i has an integer a_i written on it.
For every integer k from 1 through N, solve the following problem:

We will make a sequence by lining up the integers written on the vertices along the shortest path from Vertex 1 to Vertex k, in the order they appear. Find the length of the longest increasing subsequence of this sequence.

Here, the longest increasing subsequence of a sequence A of length L is the subsequence A_{i_1} , A_{i_2} , ... , A_{i_M} with the greatest possible value of M such that 1 \leq i_1 < i_2 < ... < i_M \leq L and A_{i_1} < A_{i_2} < ... < A_{i_M}.

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq a_i \leq 10^9

1 \leq u_i , v_i \leq N

u_i \neq v_i

The given graph is a tree.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 ... a_N
u_1 v_1
u_2 v_2
:
u_{N-1} v_{N-1}

Output

Print N lines. The k-th line, print the length of the longest increasing subsequence of the sequence obtained from the shortest path from Vertex 1 to Vertex k.

Sample Input 1

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

Sample Output 1

1
2
3
3
4
4
5
2
2
3

For example, the sequence A obtained from the shortest path from Vertex 1 to Vertex 5 is 1,2,5,3,4. Its longest increasing subsequence is A_1, A_2, A_4, A_5, with the length of 4.



Sample input:
10
1 2 5 3 4 6 7 3 2 4
1 2
2 3
3 4
4 5
3 6
6 7
1 8
8 9
9 10


Sample output:
1
2
3
3
4
4
5
2
2
3

Submission status: Runtime Error

Solution code:
import sys
input = sys.stdin.readline
from collections import deque
import bisect

n = int(input())
a = list(map(int,input().split()))

links = [[] for _ in range(n+1)]
for _ in range(n-1):
    v,w = map(int, input().split())
    links[v].append(w)
    links[w].append(v)

inf = 10**10
lis = [inf] * n
inf_ind = 0
parent = [-1]*(n+1)
operate = [0] * (n+1)
ans = [-1]*(n+1)
d = deque()
d.append(1)
while(d):
    print(d)
    now = d.popleft()
    if(operate[now]==0):
        p = parent[now]
        if(p!=-1):
            d.appendleft(now)
        for child in links[now]:
            if(child != p):
                parent[child] = now
                d.appendleft(child)

        a_now = a[now-1]
        ind = bisect.bisect_left(lis,a_now)
        operate[now] = (ind,lis[ind],a_now)
        lis[ind] = a_now
        if(inf_ind == ind):
            inf_ind += 1
        ans[now] = inf_ind
    else:
        ind,before,after = operate[now]
        lis[ind] = before
        if(before == inf):
            inf_ind -= 1
    # print(lis)

for i in ans[1:]:
    print(i)

Submission status: Runtime Error

Solution code:
from bisect import bisect

N = int(input())
a = list(map(int,input().split()))
g = [[] for _ in range(N)]
for i in range(N-1):
    u,v = map(int,input().split())
    u -= 1
    v -= 1
    g[u].append(v)
    g[v].append(u)

ans = [0]*N
def dfs(t,f,l,seq):
    l = l.copy()
    seq = seq.copy()
    l.append(a[t])
    i = bisect(seq,l[-1])
    if len(seq)==i:
        seq.append(l[-1])
    else:
        seq[i]=l[-1]
    ans[t] = len(seq)
    for v in g[t]:
        if v != f:
            dfs(v,t,l,seq)
dfs(0,0,[],[])
for i in range(N):
    print(ans[i])

Submission status: Runtime Error

Solution code:
from bisect import bisect

N = int(input())
a = list(map(int,input().split()))
g = [[] for _ in range(N)]
for i in range(N-1):
    u,v = map(int,input().split())
    u -= 1
    v -= 1
    g[u].append(v)
    g[v].append(u)

ans = [0]*N
def dfs(t,f,l,seq):
    l = l.copy()
    seq = seq.copy()
    l.append(a[t])
    print(l,seq)
    i = bisect(seq,l[-1])
    if len(seq)==i:
        seq.append(l[-1])
    else:
        seq[i]=l[-1]
    ans[t] = len(seq)
    for v in g[t]:
        if v != f:
            dfs(v,t,l,seq)
dfs(0,0,[],[])
for i in range(N):
    print(ans[i])

Submission status: Runtime Error

Solution code:
from bisect import bisect

N = int(input())
a = list(map(int,input().split()))
g = [[] for _ in range(N)]
for i in range(N-1):
    u,v = map(int,input().split())
    u -= 1
    v -= 1
    g[u].append(v)
    g[v].append(u)

ans = [0]*N
def dfs(t,f,l,seq):
    l = l.copy()
    seq = seq.copy()
    l.append(a[t])
    print(l,seq)
    i = bisect(seq,l[-1])
    if len(seq)==i:
        seq.append(l[-1])
    else:
        seq[i]=l[-1]
    ans[t] = len(seq)
    for v in g[t]:
        if v != f:
            dfs(v,t,l,seq)
dfs(0,0,[],[])
for i in range(N):
    print(ans[i])

Submission status: Runtime Error

Solution code:
class SegmentTree:
	def __init__(self, n, *, init = None, data = None, merge = None, update = None, list = list):
		if init != None and data != None:
			raise Error("init and data cannot be specified at a time")
		if init == None and data == None:
			init = lambda l, r: []
		self.n = n
		data_table = []
		if data:
			data_table.append((1, data))
		else:
			data_table.append((1, list(init(i, i + 1) for i in range(n))))
		
		w = 2
		if merge == None:
			while w <= n:
				data_table.append((w, list(init(i, i + w) for i in range(0, ((n - 1) // w + 1) * w, w))))
				w *= 2
		else:
			last_data = data_table[0][1]
			while w <= n:
				if len(last_data) % 2 == 0:
					new_data = list(merge(last_data[i * 2], last_data[i * 2 + 1]) for i in range(0, (n - 1) // w + 1))
				else:
					new_data = list(merge(last_data[i * 2], last_data[i * 2 + 1]) for i in range(0, (n - 1) // w)) + list((merge(last_data[-1], None), ))
				data_table.append((w, new_data))
				last_data = new_data
				w *= 2
		self._update = update
		self.data_table = data_table
	
	def update(self, i, value):
		if self._update != None:
			data = self.data_table[0][1]
			data[i] = value
			last_data = data
			for w, data in self.data_table[1:]:
				j = i // w
				k = j * 2
				if k + 1 < len(last_data):
					data[j] = self._update(data[j], last_data[k], last_data[k + 1])
				else:
					data[j] = self._update(data[j], last_data[k], None)
					pass
				last_data = data
		else:
			raise Error("update method not given")
	
	def data_at(self, i):
		for w, data_list in self.data_table:
			yield data_list[i // w]
	
	def data_range(self, s, e = None):
		if e == None:
			e = s
			s = 0
		if s == 0:
			for w, data_list in reversed(self.data_table):
				if e % (w * 2) >= w:
					yield data_list[e // w - 1]
		elif s < e:
			for w, data_list in self.data_table:
				w2 = w * 2
				m = s % w2
				new_s = s + w2 - m
				if new_s > e:
					break
				if m != 0:
					yield data_list[s // w]
					s = new_s
			if s == e:
				return
			for w, data_list in reversed(self.data_table):
				new_s = s + w
				if new_s <= e:
					yield data_list[s // w]
					s = new_s
	
	def check(self, merge):
		last_data = self.data_table[0][1]
		for w, data in self.data_table[1:]:
			if len(last_data) % 2 == 0:
				new_data = tuple(merge(last_data[i * 2], last_data[i * 2 + 1]) for i in range(0, (self.n - 1) // w + 1))
			else:
				new_data = tuple(merge(last_data[i * 2], last_data[i * 2 + 1]) for i in range(0, (self.n - 1) // w)) + (last_data[-1], )
			if new_data != data:
				print(new_data)
				print(data)
				raise "hoge"
			last_data = new_data
			w *= 2
	
	def output(self, func = None):
		if func == None:
			func = lambda x: str(x)
		for w, data_list in self.data_table:
			print(f"#{w}: " + ", ".join(func(data) for data in data_list))
			pass

N = int(input())
a_list = list(map(int, input().split()))

a_items = list(set(a_list))
a_items.sort()
a_table = {}
for i, a in enumerate(a_items):
	a_table[a] = i

graph = [[] for _ in range(N)]
for _ in range(N - 1):
	u, v = map(int, input().split())
	u -= 1
	v -= 1
	graph[u].append(v)
	graph[v].append(u)

def merge(d1, d2):
	if d1 == None:
		return d2
	if d2 == None:
		return d1
	return max(d1, d2)

data = [None] * len(a_table)
st = SegmentTree(len(a_table), data = data, merge = merge, update = lambda d, d1, d2: merge(d1, d2))

stack = [[0, 0, None]]
st.update(a_table[a_list[0]], 1)

results = [None] * N
results[0] = 1
while stack:
	pair = stack[-1]
	cur, index, org = pair
	a = a_table[a_list[cur]]
	
#	print(cur, st.data_table[0][1])
	
	neighbours = graph[cur]
	if index >= len(neighbours):
		st.update(a, org)
		stack.pop()
	else:
		nxt = neighbours[index]
		if results[nxt] == None:
			n_a = a_table[a_list[nxt]]
			if n_a > 0:
				l = None
				for d in st.data_range(n_a):
					if l == None or l < d:
						l = d
				if l == None:
					l = 0
			else:
				l = 0
			results[nxt] = l + 1
			n_org = st.data_table[0][1][n_a]
			st.update(n_a, l + 1)
			stack.append([nxt, 0, org])
		pair[1] = index + 1

for l in results:
	print(l)

Submission status: Runtime Error

Solution code:
import sys
from bisect import bisect_left, bisect_right
sys.setrecursionlimit(10**9)
def input(): return sys.stdin.readline().strip()


def main():
    N = int(input())
    A = list(map(int, input().split()))
    repn = [[] for _ in range(N)]
    for _ in range(N - 1):
        u, v = map(int, input().split())
        repn[u - 1].append(v - 1)
        repn[v - 1].append(u - 1)
    
    length = [0] * (N + 1)
    dp = [-1]

    """
    やはり各頂点でLIS配列を取ると配列コピーの時間がかかってTLEするので、
    配列は唯一つを扱って、DFSからバックするときに配列も元に戻す操作を行いたい
    （ここの実装の仕方がわからなかった）

    これはdfsを再帰で書いた後に復元操作を追記すれば異常に楽に書ける。。。
    """

    def dfs(v, p=N):
        if A[v] > dp[-1]:
            dp.append(A[v])
            length[v] = length[p] + 1
            for u in repn[v]:
                if u == p: continue
                dfs(u, v)
            dp.pop()
        else:
            idx = bisect_right(dp, A[v])
            old = dp[idx]
            dp[idx] = A[v]
            length[v] = length[p]
            for u in repn[v]:
                if u == p: continue
                dfs(u, v)
            dp[idx] = old
        #print("v={}, len={}, dp={}".format(v, length[v], dp))

    dfs(0)
    length.pop()
    for ans in length:
        print(ans)

if __name__ == "__main__":
    main()

Submission status: Runtime Error

Solution code:
import sys
from bisect import bisect_left, bisect_right
sys.setrecursionlimit(10**6)
def input(): return sys.stdin.readline().strip()


def main():
    N = int(input())
    A = list(map(int, input().split()))
    repn = [[] for _ in range(N)]
    for _ in range(N - 1):
        u, v = map(int, input().split())
        repn[u - 1].append(v - 1)
        repn[v - 1].append(u - 1)
    
    length = [0] * (N + 1)
    dp = [-1]

    """
    やはり各頂点でLIS配列を取ると配列コピーの時間がかかってTLEするので、
    配列は唯一つを扱って、DFSからバックするときに配列も元に戻す操作を行いたい
    （ここの実装の仕方がわからなかった）

    これはdfsを再帰で書いた後に復元操作を追記すれば異常に楽に書ける。。。
    """

    def dfs(v, p=N):
        if A[v] > dp[-1]:
            dp.append(A[v])
            length[v] = length[p] + 1
            for u in repn[v]:
                if u == p: continue
                dfs(u, v)
            dp.pop()
        else:
            idx = bisect_right(dp, A[v])
            old = dp[idx]
            dp[idx] = A[v]
            length[v] = length[p]
            for u in repn[v]:
                if u == p: continue
                dfs(u, v)
            dp[idx] = old
        #print("v={}, len={}, dp={}".format(v, length[v], dp))

    dfs(0)
    length.pop()
    for ans in length:
        print(ans)


if __name__ == "__main__":
    main()

Submission status: Runtime Error

Solution code:
import sys
from bisect import bisect_left, bisect_right
from copy import deepcopy
def input(): return sys.stdin.readline().strip()


def main():
    N = int(input())
    A = list(map(int, input().split()))
    repn = [[] for _ in range(N)]
    for _ in range(N - 1):
        u, v = map(int, input().split())
        repn[u - 1].append(v - 1)
        repn[v - 1].append(u - 1)
    
    length = [0] * (N + 1)
    dp = [-1]

    """
    やはり各頂点でLIS配列を取ると配列コピーの時間がかかってTLEするので、
    配列は唯一つを扱って、DFSからバックするときに配列も元に戻す操作を行いたい
    （ここの実装の仕方がわからなかった）

    これはdfsを再帰で書いた後に復元操作を追記すれば異常に楽に書ける。。。
    """

    def dfs(v, p=N):
        if A[v] > dp[-1]:
            dp.append(A[v])
            length[v] = length[p] + 1
            for u in repn[v]:
                if u == p: continue
                dfs(u, v)
            dp.pop()
        else:
            idx = bisect_right(dp, A[v])
            old = dp[idx]
            dp[idx] = A[v]
            length[v] = length[p]
            for u in repn[v]:
                if u == p: continue
                dfs(u, v)
            dp[idx] = old
        #print("v={}, len={}, dp={}".format(v, length[v], dp))

    dfs(0)
    length.pop()
    for ans in length:
        print(ans)




if __name__ == "__main__":
    main()

Submission status: Runtime Error

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

n = int(input())
al = list(map(int,input().split()))

from collections import defaultdict
G = defaultdict(list)

for _ in range(n-1):
    u,v = map(int,input().split())
    G[u-1].append(v-1)
    G[v-1].append(u-1)

import bisect
ansl = [0 for i in range(n)]
dp = [float("inf") for _ in range(n)]
used = [0 for i in range(n)]
used[0] = 1


stack = []
def dfs(pos):
    idx = bisect.bisect_left(dp, al[pos])
    stack.append((idx, dp[idx]))
    dp[idx] = min(al[pos], dp[idx])
    ansl[pos] = bisect.bisect_left(dp, 10**18)
    for v in G[pos]:
        if used[v] == 0:
            used[v] = 1
            dfs(v)
            idx, k = stack.pop()
            dp[idx] = k


dfs(0)
flag = False
for i in range(n):
    print(ansl[i])

Submission status: Runtime Error

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

n = int(input())
al = list(map(int,input().split()))

from collections import defaultdict
G = defaultdict(list)

for _ in range(n-1):
    u,v = map(int,input().split())
    G[u-1].append(v-1)
    G[v-1].append(u-1)

import bisect
ansl = [0 for i in range(n)]
dp = [float("inf") for _ in range(n)]
used = [0 for i in range(n)]
used[0] = 1


stack = []
def dfs(pos, dp):
    idx = bisect.bisect_right(dp, al[pos])
    stack.append((idx, dp[idx]))
    dp[idx] = min(al[pos], dp[idx])
    ansl[pos] = bisect.bisect_left(dp, 10**18)
    for v in G[pos]:
        if used[v] == 0:
            used[v] = 1
            dfs(v, dp)
            idx, k = stack.pop()
            dp[idx] = k


dfs(0, dp)
flag = False
for i in range(n):
    print(ansl[i])

Submission status: Runtime Error

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

n = int(input())
al = list(map(int,input().split()))

from collections import defaultdict
G = defaultdict(list)

for _ in range(n-1):
    u,v = map(int,input().split())
    G[u-1].append(v-1)
    G[v-1].append(u-1)

import bisect
ansl = [0 for i in range(n)]
dp = [float("inf") for _ in range(n)]
used = [0 for i in range(n)]
used[0] = 1


stack = []
def dfs(pos, dp):
    idx = bisect.bisect_right(dp, al[pos])
    stack.append((idx, dp[idx]))
    dp[idx] = min(al[pos], dp[idx])
    ansl[pos] = bisect.bisect_left(dp, 10**18) 
    for v in G[pos]:
        if used[v] == 0:
            used[v] = 1
            dfs(v, dp)
            idx, k = stack.pop()
            dp[idx] = k


dfs(0, dp)
flag = False
for i in range(n):
    print(ansl[i])

Submission status: Runtime Error

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

n = int(input())
al = list(map(int,input().split()))

from collections import defaultdict
G = defaultdict(list)

for _ in range(n-1):
    u,v = map(int,input().split())
    G[u-1].append(v-1)
    G[v-1].append(u-1)

import bisect
ansl = [0 for i in range(n)]
dp = [float("inf") for _ in range(n+1)]
dp[0] = -1
used = [0 for i in range(n)]
used[0] = 1


stack = []
def dfs(pos, dp):
    idx = bisect.bisect_right(dp, al[pos])
    stack.append((idx, dp[idx]))
    dp[idx] = min(al[pos], dp[idx])
    ansl[pos] = bisect.bisect_left(dp, 10**18) - 1
    for v in G[pos]:
        if used[v] == 0:
            used[v] = 1
            dfs(v, dp)
            idx, k = stack.pop()
            dp[idx] = k


dfs(0, dp)
flag = False
for i in range(n):
    print(ansl[i])

Submission status: Runtime Error

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

n = int(input())
al = list(map(int,input().split()))

from collections import defaultdict
G = defaultdict(list)

for _ in range(n-1):
    u,v = map(int,input().split())
    G[u-1].append(v-1)
    G[v-1].append(u-1)

from bisect import bisect
ansl = [0 for i in range(n)]
dp = [float("inf") for _ in range(n+1)]
dp[0] = -1
used = [0 for i in range(n)]
used[0] = 1


stack = []
def dfs(pos, dp):
    idx = bisect(dp, al[pos] - 1)
    stack.append((idx, dp[idx]))
    dp[idx] = min(al[pos], dp[idx])
    ansl[pos] = max(bisect(dp,10**18) - 1, 0)
    for v in G[pos]:
        if used[v] == 0:
            used[v] = 1
            dfs(v, dp)
            idx, k = stack.pop()
            dp[idx] = k


dfs(0, dp)
flag = False
for i in range(n):
    print(ansl[i])

Submission status: Runtime Error

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

n = int(input())
al = list(map(int,input().split()))

from collections import defaultdict
G = defaultdict(list)

for _ in range(n-1):
    u,v = map(int,input().split())
    G[u-1].append(v-1)
    G[v-1].append(u-1)

from bisect import bisect
ansl = [0 for i in range(n)]
dp = [float("inf") for _ in range(n+1)]
dp[0] = -1
used = [0 for i in range(n)]
used[0] = 1


stack = []
def dfs(pos, dp):
    idx = bisect(dp, al[pos] - 1)
    stack.append((idx, dp[idx]))
    dp[idx] = min(al[pos], dp[idx])
    ansl[pos] = bisect(dp,10**18) - 1
    for v in G[pos]:
        if used[v] == 0:
            used[v] = 1
            dfs(v, dp)
            idx, k = stack.pop()
            dp[idx] = k


dfs(0, dp)
flag = False
for i in range(n):
    print(ansl[i])

Submission status: Runtime Error

Solution code:
from collections import deque
from bisect import bisect_left, bisect_right
import sys
input = sys.stdin.readline


def eular_tour(tree: list, root: int):
    """根をrootとしたときの頂点に対するオイラーツアーを行う
    posの部分木が区間[begin[pos], end[pos])に対応する
    """
    n = len(tree)
    res = []
    visited = [False] * n
    visited[root] = True
    q = deque([root])
    while q:
        pos = q.pop()
        res.append(pos)
        for next_pos in tree[pos]:
            if visited[next_pos]:
                continue
            else:
                visited[next_pos] = True
                q.append(pos)
                q.append(next_pos)
    return res


n = int(input())
a = list(map(int, input().split()))
info = [list(map(int, input().split())) for i in range(n - 1)]

tree = [[] for i in range(n)]
for aa, b in info:
    aa -= 1
    b -= 1
    tree[aa].append(b)
    tree[b].append(aa)

res = eular_tour(tree, 0)

array_ind = [0]
array_val = [a[0]]
lis_array = [a[0]]
ans = [0] * n
ans[0] = 1

# (-1, -1): remove array
# (pos, val): change array
stack1 = []
stack2 = []
for ind in res[1:]:
    if len(array_ind) <= 1 or array_ind[-2] != ind:
        val = a[ind]
        array_ind.append(ind)
        array_val.append(val)
        if val > lis_array[-1]:
            lis_array.append(val)
            stack1.append(-1)
            stack2.append(-1)
        else:
            pos = bisect_left(lis_array, val)
            stack1.append(pos)
            stack2.append(lis_array[pos])
            lis_array[pos] = val
        ans[ind] = len(lis_array)
    else:
        del array_ind[-1]
        del array_val[-1]
        pos = stack1.pop()
        val = stack2.pop
        if pos == -1:
            del lis_array[-1]
        else:
            lis_array[pos] = val

for i in range(n):
    print(ans[i])

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(1000000)
def input():
    return sys.stdin.readline()
n = int(input())
aa = {}
j = 0
for i in [int(i) for i in input().split()]:
    if i in aa:
        aa[i].append(j)
    else:
        aa[i] = [j]
    j += 1
a = [0] * n
k = 1
for i in sorted(list(aa)):
    for j in aa[i]:
        a[j] = k
    k += 1

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, i=0):
        j = i - (1 << ((i + 1).bit_length() - 1))+1
        length = 1 << (self.logn - (i + 1).bit_length() + 1)
        ll = j * length
        rr = (j + 1) * length
        if l <= ll and rr <= r:
            return self.b[i]
        elif rr <= l or r <= ll:
            return self.one
        else:
            return self.func(self.get_segment(l, r, i * 2 + 1),
                             self.get_segment(l, r, i * 2 + 2))


e = [[] for _ in range(n)]
for _ in range(n - 1):
    aa, bb = [int(i) - 1 for i in input().split()]
    e[aa].append(bb)
    e[bb].append(aa)
seg = SegmentTree([-1] * (max(a)+10), max, -1)
ans1 = [0] * n
ans1[0] = 1
ans2 = [0] * n
ans2[0] = 1


def dfs(i=0, r=-1, x=[]):
    if r == -1:
        pass
    else:
        y = seg.get_segment(0, a[i])
        if y == -1:
            ans1[i] = 1
        else:
            ans1[i] = ans1[x[y]] + 1
        ans2[i] = max(ans1[r], ans1[i])

    be = seg.b[a[i]]
    seg.update_func(a[i], len(x))
    x.append(i)
    for j in e[i]:
        if j == r:
            continue
        dfs(j, i, x)
    x.pop()
    seg.update(a[i], be)
    if (be >= len(x)):
        exit()


dfs()
for i in ans2:
    print(i)

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(1000000)
def input():
    return sys.stdin.readline()
n = int(input())
aa = {}
j = 0
for i in [int(i) for i in input().split()]:
    if i in aa:
        aa[i].append(j)
    else:
        aa[i] = [j]
    j += 1
a = [0] * n
k = 1
for i in sorted(list(aa)):
    for j in aa[i]:
        a[j] = k
    k += 1


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, i=0):
        j = i - (1 << ((i + 1).bit_length() - 1))+1
        length = 1 << (self.logn - (i + 1).bit_length() + 1)
        ll = j * length
        rr = (j + 1) * length
        if l <= ll and rr <= r:
            return self.b[i]
        elif rr <= l or r <= ll:
            return self.one
        else:
            return self.func(self.get_segment(l, r, i * 2 + 1),
                             self.get_segment(l, r, i * 2 + 2))


e = [[] for _ in range(n)]
for _ in range(n - 1):
    aa, bb = [int(i) - 1 for i in input().split()]
    e[aa].append(bb)
    e[bb].append(aa)
seg = SegmentTree([-1] * (max(a)+10), max, -1)
ans1 = [0] * n
ans1[0] = 1
ans2 = [0] * n
ans2[0] = 1


def dfs(i=0, r=-1, x=[]):
    if r == -1:
        pass
    else:
        y = seg.get_segment(0, a[i])
        if y == -1:
            ans1[i] = 1
        else:
            ans1[i] = ans1[x[y]] + 1
        ans2[i] = max(ans1[r], ans1[i])

    be = seg.b[a[i]]
    seg.update_func(a[i], len(x))
    x.append(i)
    for j in e[i]:
        if j == r:
            continue
        dfs(j, i, x)
    x.pop()
    seg.update(a[i], be)


dfs()
for i in ans2:
    print(i)

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(1000000)
def input():
    return sys.stdin.readline()
n = int(input())
aa = {}
j = 0
for i in [int(i) for i in input().split()]:
    if i in aa:
        aa[i].append(j)
    else:
        aa[i] = [j]
    j += 1
a = [0] * n
k = 1
for i in sorted(list(aa)):
    for j in aa[i]:
        a[j] = k
    k += 1


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, i=0):
        j = i - (1 << ((i + 1).bit_length() - 1))+1
        length = 1 << (self.logn - (i + 1).bit_length() + 1)
        ll = j * length
        rr = (j + 1) * length
        if l <= ll and rr <= r:
            return self.b[i]
        elif rr <= l or r <= ll:
            return self.one
        else:
            return self.func(self.get_segment(l, r, i * 2 + 1),
                             self.get_segment(l, r, i * 2 + 2))


e = [[] for _ in range(n)]
for _ in range(n - 1):
    aa, bb = [int(i) - 1 for i in input().split()]
    e[aa].append(bb)
    e[bb].append(aa)
seg = SegmentTree([-1] * (n+1), max, -1)
ans1 = [0] * n
ans1[0] = 1
ans2 = [0] * n


def dfs(i=0, r=-1, x=[]):
    if r == -1:
        pass
    else:
        y = seg.get_segment(0, a[i])
        if y == -1:
            ans1[i] = 1
        else:
            ans1[i] = ans1[x[y]] + 1
    ans2[i] = max(ans1[r], ans1[i])

    be = seg.b[a[i]]
    seg.update_func(a[i], len(x))
    x.append(i)
    for j in e[i]:
        if j == r:
            continue
        dfs(j, i, x)
    x.pop()
    seg.update(a[i], be)


dfs()
for i in ans2:
    print(i)

Submission status: Runtime Error

Solution code:
n = int(input())
aa = {}
j = 0
for i in [int(i) for i in input().split()]:
    if i in aa:
        aa[i].append(j)
    else:
        aa[i] = [j]
    j += 1
a = [0] * n
k = 1
for i in sorted(list(aa)):
    for j in aa[i]:
        a[j] = k
    k += 1


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, i=0):
        j = i - (1 << ((i + 1).bit_length() - 1))+1
        length = 1 << (self.logn - (i + 1).bit_length() + 1)
        ll = j * length
        rr = (j + 1) * length
        if l <= ll and rr <= r:
            return self.b[i]
        elif rr <= l or r <= ll:
            return self.one
        else:
            return self.func(self.get_segment(l, r, i * 2 + 1),
                             self.get_segment(l, r, i * 2 + 2))


e = [[] for _ in range(n)]
for _ in range(n - 1):
    aa, bb = [int(i) - 1 for i in input().split()]
    e[aa].append(bb)
    e[bb].append(aa)
seg = SegmentTree([-1] * (n+1), max, -1)
ans1 = [0] * n
ans1[0] = 1
ans2 = [0] * n


def dfs(i=0, r=-1, x=[]):
    if r == -1:
        pass
    else:
        y = seg.get_segment(0, a[i])
        if y == -1:
            ans1[i] = 1
        else:
            ans1[i] = ans1[x[y]] + 1
    ans2[i] = max(ans1[r], ans1[i])

    be = seg.b[a[i]]
    seg.update_func(a[i], len(x))
    x.append(i)
    for j in e[i]:
        if j == r:
            continue
        dfs(j, i, x)
    x.pop()
    seg.update(a[i], be)


dfs()
for i in ans2:
    print(i)

Submission status: Runtime Error

Solution code:
import bisect
import sys
sys.setrecurtionlimit(10**7)

def dfs(v,l,tr):
  ans[v]=l
  for u in g[v]:
    if checked[u]==0:
      checked[u]=1
      pos=bisect.bisect_left(tr,arr[u])
      if pos==l:
        dfs(u,l+1,tr+[arr[u]])
      elif tr[pos]==arr[u]:
        dfs(u,l,tr)
      else:
        dfs(u,l,tr[:pos]+[arr[u]]+tr[pos+1:])

n=int(input())
arr=[0]+list(map(int,input().split()))
g=[[] for _ in range(n+1)]
for _ in range(n-1):
  a,b=map(int,input().split())
  g[a].append(b)
  g[b].append(a)
ans=[0]*(n+1)
checked=[0]*(n+1)
checked[1]=1
dfs(1,1,[arr[1]])
for i in range(1,n+1):
  print(ans[i])

Submission status: Runtime Error

Solution code:
import bisect
import sys
sys.setrecurtionlimit(10**8)

def dfs(v,l,tr):
  ans[v]=l
  for u in g[v]:
    if checked[u]==0:
      checked[u]=1
      pos=bisect.bisect_left(tr,arr[u])
      if pos==l:
        dfs(u,l+1,tr+[arr[u]])
      elif tr[pos]==arr[u]:
        dfs(u,l,tr)
      else:
        dfs(u,l,tr[:pos]+[arr[u]]+tr[pos+1:])

n=int(input())
arr=[0]+list(map(int,input().split()))
g=[[] for _ in range(n+1)]
for _ in range(n-1):
  a,b=map(int,input().split())
  g[a].append(b)
  g[b].append(a)
ans=[0]*(n+1)
checked=[0]*(n+1)
checked[1]=1
dfs(1,1,[arr[1]])
for i in range(1,n+1):
  print(ans[i])

Submission status: Runtime Error

Solution code:
import bisect

def dfs(v):
  pos=bisect.bisect_left(dp,arr[v])
  changes.append((pos,dp[pos]))
  dp[pos]=arr[v]
  ans[v]=bisect.bisect_left(dp,10**18)
  for u in g[v]:
    if checked[u]==0:
      checked[u]=1
      dfs(u)
  pos,val=changes.pop()
  dp[pos]=val

n=int(input())
arr=[0]+list(map(int,input().split()))
g=[[] for _ in range(n+1)]
for _ in range(n-1):
  a,b=map(int,input().split())
  g[a].append(b)
  g[b].append(a)
ans=[0]*(n+1)
checked=[0]*(n+1)
checked[1]=1
dp=[10**18 for _ in range(n+1)]
changes=[]
dfs(1)
for i in range(1,n+1):
  print(ans[i])