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.

Solution in C# (.NET Core 3.1.201) (judge verdict: Wrong Answer)

#region いつもの
using System;
using System.Collections.Generic;
using System.Linq;
using AtCoderProject;
using ConsoleReader = AtCoderProject.Reader.ConsoleReader;
using IEnumerable = System.Collections.IEnumerable;
using IEnumerator = System.Collections.IEnumerator;
using Unsafe = System.Runtime.CompilerServices.Unsafe;
using BigInteger = System.Numerics.BigInteger;
using TextReader = System.IO.TextReader;
using StringBuilder = System.Text.StringBuilder;
using static AtCoderProject.Global;
using static AtCoderProject.NumGlobal;
namespace AtCoderProject { public static class Global { public static T[] NewArray<T>(int len0, T value) => new T[len0].Fill(value); public static T[] NewArray<T>(int len0, Func<T> factory) { var arr = new T[len0]; for (int i = 0; i < arr.Length; i++) arr[i] = factory(); return arr; } public static T[][] NewArray<T>(int len0, int len1, T value) where T : struct { var arr = new T[len0][]; for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, value); return arr; } public static T[][] NewArray<T>(int len0, int len1, Func<T> factory) { var arr = new T[len0][]; for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, factory); return arr; } public static T[][][] NewArray<T>(int len0, int len1, int len2, T value) where T : struct { var arr = new T[len0][][]; for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, value); return arr; } public static T[][][] NewArray<T>(int len0, int len1, int len2, Func<T> factory) { var arr = new T[len0][][]; for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, factory); return arr; } public static T[][][][] NewArray<T>(int len0, int len1, int len2, int len3, T value) where T : struct { var arr = new T[len0][][][]; for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, len3, value); return arr; } public static T[][][][] NewArray<T>(int len0, int len1, int len2, int len3, Func<T> factory) { var arr = new T[len0][][][]; for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, len3, factory); return arr; } private class ComparerReverseImpl<T> : Comparer<T> where T : IComparable<T> { public override int Compare(T y, T x) => x.CompareTo(y); public override bool Equals(object obj) => obj != null && GetType() == obj.GetType(); public override int GetHashCode() => GetType().GetHashCode(); } public static IComparer<T> ComparerReverse<T>() where T : IComparable<T> => new ComparerReverseImpl<T>(); public static string AllLines<T>(IEnumerable<T> source) => string.Join("\n", source); public static string AllJoin<T>(IEnumerable<T> source) => string.Join(" ", source); } public static class NumGlobal { public static int Pow(int x, int y) { int res = 1; for (; y > 0; y >>= 1) { if ((y & 1) == 1) res *= x; x *= x; } return res; } public static BigInteger ParseBigInteger(ReadOnlySpan<char> s) { BigInteger res; if (s.Length % 9 == 0) res = 0; else { res = new BigInteger(int.Parse(s.Slice(0, s.Length % 9))); s = s.Slice(s.Length % 9); } while (s.Length > 0) { var sp = s.Slice(0, 9); res *= 1000_000_000; res += int.Parse(sp); s = s.Slice(9); } return res; } public static int BitCount(int x) { x -= (x >> 1) & 0x55555555; x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0f0f0f0f; x += x >> 8; x += x >> 16; return x & 0x3f; } public static int BitCount(long x) { x -= (x >> 1) & 0x5555555555555555; x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f; x += x >> 8; x += x >> 16; x += x >> 32; return (int)(x & 0x0000007f); } public static int MSB(int x) { x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return BitCount(x) - 1; } public static int MSB(long x) { x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x |= x >> 32; return BitCount(x) - 1; } public static int LSB(int x) { x |= x << 1; x |= x << 2; x |= x << 4; x |= x << 8; x |= x << 16; return 32 - BitCount(x); } public static int LSB(long x) { x |= x << 1; x |= x << 2; x |= x << 4; x |= x << 8; x |= x << 16; x |= x << 32; return 64 - BitCount(x); } } public static class Ext { public static bool UpdateMax(this ref int r, int val) { if (r < val) { r = val; return true; } return false; } public static bool UpdateMax(this ref long r, long val) { if (r < val) { r = val; return true; } return false; } public static bool UpdateMin(this ref int r, int val) { if (r > val) { r = val; return true; } return false; } public static bool UpdateMin(this ref long r, long val) { if (r > val) { r = val; return true; } return false; } public static long ToLong(this int i) => i; public static T[] Fill<T>(this T[] arr, T value) { Array.Fill(arr, value); return arr; } public static T[] Sort<T>(this T[] arr) { Array.Sort(arr); return arr; } public static string[] Sort(this string[] arr) => Sort(arr, StringComparer.OrdinalIgnoreCase); public static T[] Sort<T, U>(this T[] arr, Func<T, U> selector) where U : IComparable<U> => Sort(arr, (a, b) => selector(a).CompareTo(selector(b))); public static T[] Sort<T>(this T[] arr, Comparison<T> comparison) { Array.Sort(arr, comparison); return arr; } public static T[] Sort<T>(this T[] arr, IComparer<T> comparer) { Array.Sort(arr, comparer); return arr; } public static T[] Reverse<T>(this T[] arr) { Array.Reverse(arr); return arr; } public static (int index, T max) MaxBy<T>(this T[] arr) where T : IComparable<T> { T max = arr[0]; int maxIndex = 0; for (int i = 0; i < arr.Length; i++) { if (max.CompareTo(arr[i]) < 0) { max = arr[i]; maxIndex = i; } } return (maxIndex, max); } public static (TSource item, TMax max) MaxBy<TSource, TMax>(this IEnumerable<TSource> source, Func<TSource, TMax> maxBySelector) where TMax : IComparable<TMax> { TMax max; TSource maxByItem; var e = source.GetEnumerator(); e.MoveNext(); maxByItem = e.Current; max = maxBySelector(maxByItem); while (e.MoveNext()) { var item = e.Current; var next = maxBySelector(item); if (max.CompareTo(next) < 0) { max = next; maxByItem = item; } } return (maxByItem, max); } public static (int index, T min) MinBy<T>(this T[] arr) where T : IComparable<T> { T min = arr[0]; int minIndex = 0; for (int i = 0; i < arr.Length; i++) { if (min.CompareTo(arr[i]) > 0) { min = arr[i]; minIndex = i; } } return (minIndex, min); } public static (TSource item, TMin min) MinBy<TSource, TMin>(this IEnumerable<TSource> source, Func<TSource, TMin> minBySelector) where TMin : IComparable<TMin> { TMin min; TSource minByItem; var e = source.GetEnumerator(); e.MoveNext(); minByItem = e.Current; min = minBySelector(minByItem); while (e.MoveNext()) { var item = e.Current; var next = minBySelector(item); if (min.CompareTo(next) > 0) { min = next; minByItem = item; } } return (minByItem, min); } public static IComparer<T> Reverse<T>(this IComparer<T> comparer) => Comparer<T>.Create((x, y) => comparer.Compare(y, x)); public static Dictionary<TKey, int> GroupCount<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) => source.GroupBy(keySelector).ToDictionary(g => g.Key, g => g.Count()); public static Dictionary<TKey, int> GroupCount<TKey>(this IEnumerable<TKey> source) => source.GroupCount(i => i); public static TValue Get<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key) { dic.TryGetValue(key, out var v); return v; } public static TValue GetOrInit<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) { if (dic.TryGetValue(key, out var v)) return v; return dic[key] = value; } } public class ΔDebugView<T> { private IEnumerable<T> collection; public ΔDebugView(IEnumerable<T> collection) { this.collection = collection ?? throw new ArgumentNullException(nameof(collection)); }[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)] public T[] Items => collection.ToArray(); } }
namespace AtCoderProject.Reader { using System.IO; using System.Text; using System.Diagnostics; using System.Runtime.CompilerServices;[DebuggerNonUserCode] public class ConsoleReader { const int BufSize = 1 << 12; private readonly byte[] buffer = new byte[BufSize]; private readonly Stream input; private readonly Encoding encoding; private int pos = 0; private int len = 0; public ConsoleReader(Stream input, Encoding encoding) { this.input = input; this.encoding = encoding; } public ConsoleReader(Stream input) : this(input, Encoding.UTF8) { } public ConsoleReader(string text) : this(new MemoryStream(Encoding.UTF8.GetBytes(text))) { } private void MoveNext() { if (++pos >= len) { len = input.Read(buffer, 0, buffer.Length); if (len == 0) { buffer[0] = 10; } pos = 0; } } public int Int { [MethodImpl(MethodImplOptions.AggressiveInlining)]            get { int res = 0; bool neg = false; while (buffer[pos] < 48) { neg = buffer[pos] == 45; MoveNext(); } do { res = res * 10 + (buffer[pos] ^ 48); MoveNext(); } while (48 <= buffer[pos]); return neg ? -res : res; } } public int Int0 => this.Int - 1; public long Long { [MethodImpl(MethodImplOptions.AggressiveInlining)]            get { long res = 0; bool neg = false; while (buffer[pos] < 48) { neg = buffer[pos] == 45; MoveNext(); } do { res = res * 10 + (buffer[pos] ^ 48); MoveNext(); } while (48 <= buffer[pos]); return neg ? -res : res; } } public long Long0 => this.Long - 1; public string String { [MethodImpl(MethodImplOptions.AggressiveInlining)]            get { var sb = new List<byte>(); while (buffer[pos] <= 32) MoveNext(); do { sb.Add(buffer[pos]); MoveNext(); } while (32 < buffer[pos]); return this.encoding.GetString(sb.ToArray()); } } public string Ascii { [MethodImpl(MethodImplOptions.AggressiveInlining)]            get { var sb = new StringBuilder(); while (buffer[pos] <= 32) MoveNext(); do { sb.Append((char)buffer[pos]); MoveNext(); } while (32 < buffer[pos]); return sb.ToString(); } } public string Line { [MethodImpl(MethodImplOptions.AggressiveInlining)]            get { var sb = new List<byte>(); while (buffer[pos] < 32) MoveNext(); do { sb.Add(buffer[pos]); MoveNext(); } while (buffer[pos] != 10 && buffer[pos] != 13); return this.encoding.GetString(sb.ToArray()); } } public double Double => double.Parse(this.Ascii);[DebuggerNonUserCode] public struct RepeatReader { ConsoleReader cr; int count; public RepeatReader(ConsoleReader cr, int count) { this.cr = cr; this.count = count; } public T[] Select<T>(Func<ConsoleReader, T> factory) { var arr = new T[count]; for (var i = 0; i < count; i++) arr[i] = factory(cr); return arr; } public string[] Line { get { var arr = new string[count]; for (var i = 0; i < count; i++) arr[i] = cr.Line; return arr; } } public string[] String { get { var arr = new string[count]; for (var i = 0; i < count; i++) arr[i] = cr.String; return arr; } } public string[] Ascii { get { var arr = new string[count]; for (var i = 0; i < count; i++) arr[i] = cr.Ascii; return arr; } } public int[] Int { get { var arr = new int[count]; for (var i = 0; i < count; i++) arr[i] = cr.Int; return arr; } } public int[] Int0 { get { var arr = new int[count]; for (var i = 0; i < count; i++) arr[i] = cr.Int0; return arr; } } public long[] Long { get { var arr = new long[count]; for (var i = 0; i < count; i++) arr[i] = cr.Long; return arr; } } public long[] Long0 { get { var arr = new long[count]; for (var i = 0; i < count; i++) arr[i] = cr.Long0; return arr; } } public double[] Double { get { var arr = new double[count]; for (var i = 0; i < count; i++) arr[i] = cr.Double; return arr; } } } public RepeatReader Repeat(int count) => new RepeatReader(this, count);[DebuggerNonUserCode] public struct SplitReader { ConsoleReader cr; public SplitReader(ConsoleReader cr) { this.cr = cr; } public string[] String { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<string>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.String); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } } public string[] Ascii { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<string>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Ascii); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } } public int[] Int { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<int>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Int); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } } public int[] Int0 { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<int>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Int0); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } } public long[] Long { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<long>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Long); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } } public long[] Long0 { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<long>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Long0); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } } public double[] Double { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<double>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Double); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } } } public SplitReader Split => new SplitReader(this); } }
public class Program
{
    [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] private ConsoleReader cr;

    public Program(ConsoleReader consoleReader) { this.cr = consoleReader; }
    static void Main() => Console.WriteLine(new Program(new ConsoleReader(Console.OpenStandardInput())).Result());
    #endregion
    public string Result() => Calc() switch { bool b => b ? "OK" : "NG", double d => d.ToString("0.####################"), object o => o.ToString(), };
    public object Calc()
    {
        var N = cr.Int;
        arr = cr.Repeat(N).Int;
        //brr = NewArray(N, -1);
        //{
        //    var pq = new PriorityQueue<int, int>();
        //    for (int i = 0; i < arr.Length; i++)
        //        pq.Add(arr[i], i);

        //    var idx = pq.data.ToArray().Sort((a, b) => pq.comparer.Compare(a.Key, b.Key));
        //    var last = -1;
        //    for (int i = 0; i < N; i++)
        //    {
        //        arr[idx[i].Value] = i;
        //        if (i > 0 && idx[i].Key == idx[i - 1].Key)
        //            brr[i] = last;
        //        else
        //            brr[i] = last = i - 1;
        //    }
        //}
        tree = new GraphBuilder(N, cr, N - 1, false).ToTree(0);
        res = new Dictionary<int, int>[N];
        res[0] = new Dictionary<int, int> { { 1, arr[0] } };
        foreach (var item in tree[0].children)
            Update(item);
        return AllLines(res.Select(d => d.Count));
    }
    void Update(int v)
    {
        var dic = new Dictionary<int, int>();
        foreach (var (score, max) in res[tree[v].root])
        {
            if (arr[v] > max)
            {
                dic.UpdateMin(score + 1, arr[v]);
            }
            dic.UpdateMax(score, max);
        }
        res[v] = dic;

        foreach (var child in tree[v].children)
        {
            Update(child);
        }
    }
    Dictionary<int, int>[] res;
    int[] arr;
    int[] brr;
    TreeNode[] tree;
}
static class ExtDic
{
    public static void UpdateMax(this Dictionary<int, int> dic, int score, int min)
    {
        if (dic.TryGetValue(score, out var cur))
        {
            if (cur < min)
                dic[score] = min;
        }
        else
            dic[score] = min;
    }
    public static void UpdateMin(this Dictionary<int, int> dic, int score, int max)
    {
        if (dic.TryGetValue(score, out var cur))
        {
            if (cur > max)
                dic[score] = max;
        }
        else
            dic[score] = max;
    }
}

class GraphBuilder
{
    private List<int>[] roots;
    private List<int>[] children;
    public GraphBuilder(int count, bool isOriented)
    {
        this.roots = new List<int>[count];
        this.children = new List<int>[count];
        for (var i = 0; i < count; i++)
        {
            if (isOriented)
            {
                this.roots[i] = new List<int>();
                this.children[i] = new List<int>();
            }
            else
            {
                this.roots[i] = this.children[i] = new List<int>();
            }
        }
    }
    public GraphBuilder(int count, ConsoleReader cr, int edgeCount, bool isOriented) : this(count, isOriented)
    {
        for (var i = 0; i < edgeCount; i++)
            this.Add(cr.Int0, cr.Int0);
    }
    public void Add(int from, int to)
    {
        children[from].Add(to);
        roots[to].Add(from);
    }
    public TreeNode[] ToTree(int root)
    {
        if (this.roots[0] != this.children[0]) throw new Exception("木には無向グラフをしたほうが良い");
        var res = new TreeNode[this.children.Length];
        res[root] = new TreeNode(root, -1, 0, this.children[root].ToArray());

        var queue = new Queue<int>();
        foreach (var child in res[root].children)
        {
            res[child] = new TreeNode(child, root, 1, Array.Empty<int>());
            queue.Enqueue(child);
        }

        while (queue.Count > 0)
        {
            var from = queue.Dequeue();
            if (res[from].root == -1)
                res[from].children = this.children[from].ToArray();
            else
            {
                var children = new List<int>(this.children[from].Count);
                foreach (var c in this.children[from])
                    if (c != res[from].root)
                        children.Add(c);

                res[from].children = children.ToArray();
            }

            foreach (var child in res[from].children)
            {
                res[child] = new TreeNode(child, from, res[from].depth + 1, Array.Empty<int>());
                queue.Enqueue(child);
            }
        }

        return res;
    }

    public Node[] ToArray() =>
        Enumerable
        .Zip(roots, children, (root, child) => (root, child))
        .Select((t, i) => new Node(i, t.root.ToArray(), t.child.ToArray()))
        .ToArray();
}
class TreeNode
{
    public TreeNode(int i, int root, int depth, int[] children)
    {
        this.index = i;
        this.root = root;
        this.children = children;
        this.depth = depth;
    }
    public readonly int index;
    public readonly int root;
    public readonly int depth;
    public int[] children;

    public override string ToString() => $"children: {string.Join(",", children)}";
    public override bool Equals(object obj)
    {
        if (obj is TreeNode)
            return this.Equals((TreeNode)obj);
        else
            return false;
    }
    public bool Equals(TreeNode other) => this.index == other.index;
    public override int GetHashCode() => this.index;
}
class Node
{
    public Node(int i, int[] roots, int[] children)
    {
        this.index = i;
        this.roots = roots;
        this.children = children;
    }
    public readonly int index;
    public readonly int[] roots;
    public readonly int[] children;

    public override string ToString() => $"children: {string.Join(",", children)}";
    public override bool Equals(object obj)
    {
        if (obj is Node)
            return this.Equals((Node)obj);
        else
            return false;
    }
    public bool Equals(Node other) => this.index == other.index;
    public override int GetHashCode() => this.index;
}

[System.Diagnostics.DebuggerDisplay("Count = {" + nameof(Count) + "}")]
class PriorityQueue<TKey, TValue>
{
    public readonly List<KeyValuePair<TKey, TValue>> data;
    public readonly IComparer<TKey> comparer;
    public PriorityQueue() : this(Comparer<TKey>.Default) { }
    public PriorityQueue(int capacity) : this(capacity, Comparer<TKey>.Default) { }
    public PriorityQueue(IComparer<TKey> comparer) { this.data = new List<KeyValuePair<TKey, TValue>>(); this.comparer = comparer; }
    public PriorityQueue(int capacity, IComparer<TKey> comparer) { this.data = new List<KeyValuePair<TKey, TValue>>(capacity); this.comparer = comparer; }
    public int Count => data.Count;
    public KeyValuePair<TKey, TValue> Peek => data[0];
    public void Add(TKey key, TValue value) { data.Add(new KeyValuePair<TKey, TValue>(key, value)); UpdateUp(data.Count - 1); }
    public KeyValuePair<TKey, TValue> Dequeue() { var res = data[0]; data[0] = data[^1]; data.RemoveAt(data.Count - 1); UpdateDown(0); return res; }
    private void UpdateUp(int i) { if (i > 0) { var p = (i - 1) >> 1; if (comparer.Compare(data[i].Key, data[p].Key) < 0) { (data[p], data[i]) = (data[i], data[p]); UpdateUp(p); } } }
    private void UpdateDown(int i) { var n = data.Count; var child = 2 * i + 1; if (child < n) { if (child != n - 1 && comparer.Compare(data[child].Key, data[child + 1].Key) > 0) child++; if (comparer.Compare(data[i].Key, data[child].Key) > 0) { (data[child], data[i]) = (data[i], data[child]); UpdateDown(child); } } }

#pragma warning disable IDE0051
    [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)] private KeyValuePair<TKey, TValue>[] Items => data.ToArray().Sort((a, b) => comparer.Compare(a.Key, b.Key));
}