#define _USE_MATH_DEFINES

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <unordered_map> 
#include <unordered_set>
#include <functional>
#include <bitset>

using namespace std;

typedef pair<long long int, long long int> P;
typedef pair<long long int, P> P2;
typedef tuple<int, int, int> T;

long long int INF = 1e18;
long long int MOD = 1e9 + 7;

int c[210000];
vector<int> E[210000];

int sz[210000]; // 部分木の大きさ
vector<int> g[210000]; // 親から子への辺
int nxt[210000]; // HL分解後の、各パスの終点
int in[210000]; // 訪問順（行きがけ順）
int out[210000]; // 部分木に含まれる訪問順（行きがけ順）の最大値
int t = 0; // 

void func(int pos, int from){
	for(int to : E[pos]){
		if(from != to){
			g[pos].push_back(to);
			func(to, pos);
		}
	}
	return;
}

void dfs_sz(int v) {
	sz[v] = 1;
	for(int &u: g[v]) {
		dfs_sz(u);
		sz[v] += sz[u];
		if(sz[u] > sz[g[v][0]]) {
			swap(u, g[v][0]);
		}
	}
}

void dfs_hld(int v) {
	in[v] = t++;
	for(int u: g[v]) {
		nxt[u] = (u == g[v][0] ? nxt[v] : u);
		dfs_hld(u);
	}
	out[v] = t;
}

int const TREE_SIZE = (1 << 20);

class SegTree{
	public:
	// コンストラクタ
	SegTree(std::function<long long int(long long int, long long int)> monoidFunc_, long long int invalidValue_){
		monoidFunc = monoidFunc_;
		invalidValue = invalidValue_;
	}
	// 値の初期化
	void init(long long int initValue){
		for(int i = 0; i < TREE_SIZE; i++){
			segTree[i] = initValue;
		}
	}
	// a番目(0-indexed)をwに変更する O(log N)
	void change(int a, long long int w){
		change_(a + 1, w);
	}
	// 区間 [a, b] (0-indexed)の値を求める O(log N)
	long long int query(int a, int b){
		return query_(a + 1, b + 2, 1, 0, TREE_SIZE / 2);
	}
	private:
	function<long long int(long long int, long long int)> monoidFunc;
	long long int invalidValue;
	long long int segTree[TREE_SIZE]; // 1-indexed

	// a番目をwに変更する O(log N)
	void change_(int a, long long int w){
		a += TREE_SIZE / 2;
		segTree[a] = w;
		for(int x = a / 2; x > 0; x /= 2){
			segTree[x] = monoidFunc(segTree[2 * x], segTree[2 * x + 1]);
		}
	}
	// 区間 [a, b) の値を求める O(log N)
	// query(a, b, 1, 0, TREE_SIZE / 2) のように呼ぶ
	long long int query_(int a, int b, int index, int l, int r){
		if(r <= a || b <= l){
			return invalidValue;
		}
		if(a <= l && r <= b){
			return segTree[index];
		}
		return monoidFunc(query_(a, b, index * 2, l, (l + r) / 2), query_(a, b, index * 2 + 1, (l + r) / 2, r));
	}
};

long long int segfunc(long long int a, long long int b){
	return a + b;
}
SegTree segTree(segfunc, 0);

vector<long long int> memo[210000];
vector<P> v;

int func2(int pos, int from){
	int ret = 1;
	for(int to : E[pos]){
		if(from != to){
			int num = func2(to, pos);
			ret += num;
			P p = P(c[pos], in[to]);
			int p1 = distance(v.begin(), lower_bound(v.begin(), v.end(), p));
			p = P(c[pos], out[to]);
			int p2 = distance(v.begin(), lower_bound(v.begin(), v.end(), p) - 1);
			num -= segTree.query(p1, p2);
			p = P(c[pos], in[pos]);
			p1 = distance(v.begin(), lower_bound(v.begin(), v.end(), p));
			long long int val = segTree.query(p1, p1);
			segTree.change(p1, val + num);
			memo[c[pos]].push_back(num);
		}
	}
	P p = P(c[pos], in[pos]);
	int p1 = distance(v.begin(), lower_bound(v.begin(), v.end(), p));
	long long int val = segTree.query(p1, p1);
	segTree.change(p1, val + 1);
	return ret;
}

int cnt[210000];

int main(){
	long long int N;
	cin >> N;
	for(int i = 0; i < N; i++){
		cin >> c[i];
		c[i] -= 1;
		cnt[c[i]] += 1;
	}
	for(int i = 0; i < N - 1; i++){
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		E[a].push_back(b);
		E[b].push_back(a);
	}
	func(0, -1);
	dfs_sz(0);
	dfs_hld(0);
	for(int i = 0; i < N; i++){
		v.push_back(P(c[i], in[i]));
	}
	sort(v.begin(), v.end());
	segTree.init(0);
	func2(0, -1);
	for(int i = 0; i < N; i++){
		long long int ans = N * (N + 1) / 2, S = cnt[i];
		for(long long int num : memo[i]){
			ans -= num * (num + 1) / 2;
			S += num;
		}
		ans -= (N - S) * (N - S + 1) / 2;
		cout << ans << endl;
	}
	return 0;
}


Measured memory_bytes: 247612