Problem:
Score : 600 points

Problem Statement

We have a tree with N vertices numbered 1 to N. The i-th edge in this tree connects Vertex a_i and b_i.
Additionally, each vertex is painted in a color, and the color of Vertex i is c_i. Here, the color of each vertex is represented by an integer between 1 and N (inclusive). The same integer corresponds to the same color; different integers correspond to different colors.

For each k=1, 2, ..., N, solve the following problem:

Find the number of simple paths that visit a vertex painted in the color k one or more times.

Note: The simple paths from Vertex u to v and from v to u are not distinguished.

Constraints

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

1 \leq c_i \leq N

1 \leq a_i,b_i \leq N

The given graph is a tree.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
c_1 c_2 ... c_N
a_1 b_1
:
a_{N-1} b_{N-1}

Output

Print the answers for k = 1, 2, ..., N in order, each in its own line.

Sample Input 1

3
1 2 1
1 2
2 3

Sample Output 1

5
4
0

Let P_{i,j} denote the simple path connecting Vertex i and j.

There are 5 simple paths that visit a vertex painted in the color 1 one or more times:

P_{1,1}\,,\,
P_{1,2}\,,\,
P_{1,3}\,,\,
P_{2,3}\,,\,
P_{3,3}

There are 4 simple paths that visit a vertex painted in the color 2 one or more times:

P_{1,2}\,,\,
P_{1,3}\,,\,
P_{2,2}\,,\,
P_{2,3}

There are no simple paths that visit a vertex painted in the color 3 one or more times.

Sample Input 2

1
1

Sample Output 2

1

Sample Input 3

2
1 2
1 2

Sample Output 3

2
2

Sample Input 4

5
1 2 3 4 5
1 2
2 3
3 4
3 5

Sample Output 4

5
8
10
5
5

Sample Input 5

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

Sample Output 5

18
15
0
14
23
0
23
0

Solution in Rust (1.42.0) (judge verdict: Accepted)

//---------- begin union_find ----------
#[allow(dead_code)]
mod union_find {
    use std;
    pub struct UF {
        parent: Vec<usize>,
        size: Vec<usize>,
        stack: Vec<Option<(usize, usize)>>,
    }
    impl UF {
        pub fn new(n: usize) -> UF {
            let mut u = UF {
                parent: vec![0; n],
                size: vec![1; n],
                stack: vec![],
            };
            u.init();
            u
        }
        pub fn init(&mut self) {
            for (i, p) in self.parent.iter_mut().enumerate() {
                *p = i;
            }
            self.size.clear();
            self.size.resize(self.parent.len(), 1);
            self.stack.clear();
        }
        pub fn root(&mut self, mut x: usize) -> usize {
            while self.parent[x] != x {
                x = self.parent[x];
            }
            x
        }
        pub fn same(&mut self, x: usize, y: usize) -> bool {
            self.root(x) == self.root(y)
        }
        pub fn unite(&mut self, mut x: usize, mut y: usize) -> Option<(usize, usize)> {
            x = self.root(x);
            y = self.root(y);
            if x == y {
                self.stack.push(None);
                return None;
            }
            if self.size[x] < self.size[y] {
                std::mem::swap(&mut x, &mut y);
            }
            self.size[x] += self.size[y];
            self.parent[y] = x;
            self.stack.push(Some((x, y)));
            Some((x, y))
        }
        pub fn undo(&mut self) -> Option<(usize, usize)> {
            self.stack
                .pop()
                .expect("union find undo error: stack is empty")
                .map(|(x, y)| {
                    self.size[x] -= self.size[y];
                    self.parent[y] = y;
                    (x, y)
                })
        }
        pub fn get_size(&mut self, x: usize) -> usize {
            let r = self.root(x);
            self.size[r]
        }
    }
}
//---------- end union_find ----------

use proconio::*;
use proconio::marker::Usize1;

fn calc(mut cnt: usize, l: usize, r: usize, e: Vec<(usize, usize, usize, usize)>, u: &mut union_find::UF, ans: &mut [usize]) {
    let m = (l + r) / 2;
    let mut left = vec![];
    let mut right = vec![];
    let mut used = 0;
    for (x, y, a, b) in e {
        if x <= l && r <= y {
            let a = u.root(a);
            let b = u.root(b);
            cnt += u.get_size(a) * u.get_size(b);
            u.unite(a, b);
            used += 1;
            continue;
        }
        if x < m {
            left.push((x, y, a, b));
        }
        if m < y {
            right.push((x, y, a, b));
        }
    }
    if l + 1 == r {
        ans[l] -= cnt;
    } else {
        calc(cnt, l, m, left, u, ans);
        calc(cnt, m, r, right, u, ans);
    }
    for _ in 0..used {
        u.undo();
    }
}

#[fastout]
fn run() {
    input! {
        n: usize,
        c: [Usize1; n],
        e: [(Usize1, Usize1); n - 1],
    }
    let mut edge = vec![];
    for &(a, b) in e.iter() {
        let x = c[a];
        let y = c[b];
        let (x, y) = (std::cmp::min(x, y), std::cmp::max(x, y));
        if x > 0 {
            edge.push((0, x, a, b));
        }
        if x + 1 < y {
            edge.push((x + 1, y, a, b));
        }
        if y + 1 < n {
            edge.push((y + 1, n, a, b));
        }
    }
    let mut ans = vec![n * (n + 1) / 2; n];
    for c in c.iter(){
        ans[*c] += 1;
    }
    let mut u = union_find::UF::new(n);
    calc(n, 0, n, edge, &mut u, &mut ans);
    for a in ans {
        println!("{}", a);
    }
}

fn main() {
    run();
}