stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

ll cal(int x) {

	return 1ll * x*(x - 1) / 2 + x;

}

ll ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

int main() {

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)scanf("%d", &c[i]);

	for (int i = 1; i < n; i++) {

		int u, v;

		scanf("%d%d", &u, &v);

		G[u].push_back(v);

		G[v].push_back(u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		printf("%lld\n", cal(n) - ans[i] - cal(n - cnt[i]));

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.369861794468824x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL cal(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += cal(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << cal(N) - ans[i] - cal(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

ll cal(int x) {

	return 1ll * x*(x+1)/2;

}

ll ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

int main() {

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)scanf("%d", &c[i]);

	for (int i = 1; i < n; i++) {

		int u, v;

		scanf("%d%d", &u, &v);

		G[u].push_back(v);

		G[v].push_back(u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		printf("%lld\n", cal(n) - ans[i] - cal(n - cnt[i]));

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.369429608176978x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL cal(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += cal(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << cal(N) - ans[i] - cal(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

inline ll cal(int x) {

	return 1ll * x*(x+1)/2;

}

ll ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

int main() {

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)scanf("%d", &c[i]);

	for (int i = 1; i < n; i++) {

		int u, v;

		scanf("%d%d", &u, &v);

		G[u].push_back(v);

		G[v].push_back(u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		printf("%lld\n", cal(n) - ans[i] - cal(n - cnt[i]));

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.369930095292311x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL cal(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += cal(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << cal(N) - ans[i] - cal(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define LL long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

	inline LL cal(int n) {

		// C(n,2) + n

		return 1LL*n*(n+1)/2;

	}

LL ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

int main() {

	//scanf("%d", &n);

	std::ios::sync_with_stdio(false);

	cin>>n;

	for (int i = 1; i <= n; i++)

		//scanf("%d", &c[i]);

		cin>>c[i];

	for (int i = 1; i < n; i++) {

		int u, v;

		//scanf("%d%d", &u, &v);

		cin>>u>>v;

		G[u].push_back(v);

		G[v].push_back(u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		cout<< cal(n) - ans[i] - cal(n - cnt[i])<<endl;

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.413027260850299x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL cal(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += cal(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << cal(N) - ans[i] - cal(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
	#include<iostream>

	#include<vector>

	using namespace std;

	#define LL	long long

	const int MAXN = 2e5+10;



	int N;

	int c[MAXN];

	vector<int> G[MAXN];

//	int tot = 0;

//	int head[MAXN], Next[MAXN], to[MAXN];



	// sub[i]: 顶点i下子树顶点的个数

	int sub[MAXN];

	// cnt[i]: 颜色为i的顶点下子树顶点的个数

	int cnt[MAXN]; 

	// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

	LL ans[MAXN];

	

	// 一开始起名count结果和c++ count()冲突，调试了半天, md

	inline LL cal(int n) {

		// C(n,2) + n

		return 1LL*n*(n+1)/2;

	}

	/*

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		sub[v] = 1;

		for(int i=head[v]; i; i=Next[i]) {

			int u = to[i];

			if(u == fa) continue;

			cnt[c[v]] = 0;	// 置0重新计数

			dfs(u, v);

			sub[v] += sub[u];

			ans[c[v]] += count(sub[u] - cnt[c[v]]);

		}

		cnt[c[v]] = tmp + sub[v];

	}

	void add(int a, int b) {

		++tot;

		Next[tot] = head[a];

		to[tot] = b;

		head[a] = tot;

	}

	*/

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		sub[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			sub[v] += sub[u];

			ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + sub[v];

	}

	

	int main() {

		std::ios::sync_with_stdio(false);

		cin>>N;

		for(int i=1; i<=N; i++) {

			cin >> c[i];

		}

		int a, b;

		for(int i=1; i<N; i++) {

			cin>>a>>b;

			G[a].push_back(b);

			G[b].push_back(a);

		}

		//dfs1(1, 0);

		dfs(1, 0);

		for(int i=1; i<=N; i++) {

			cout << cal(N) - ans[i] - cal(N-cnt[i]) << endl;

		}

		return 0;

	}


// Faster C++ solution for the same problem (measured speedup: 6.412863934556789x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL cal(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += cal(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << cal(N) - ans[i] - cal(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define LL long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

	inline LL cal(int n) {

		// C(n,2) + n

		return 1LL*n*(n+1)/2;

	}

LL ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

	

	inline void add(int a, int b) {

		G[a].push_back(b);

		G[b].push_back(a);

	}

	

int main() {

	//scanf("%d", &n);

	std::ios::sync_with_stdio(false);

	cin>>n;

	for (int i = 1; i <= n; i++)

		//scanf("%d", &c[i]);

		cin>>c[i];

	for (int i = 1; i < n; i++) {

		int u, v;

		//scanf("%d%d", &u, &v);

		cin>>u>>v;

		G[u].push_back(v);

		G[v].push_back(u);

		//add(u, v); add(v, u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		cout<< cal(n) - ans[i] - cal(n - cnt[i])<<endl;

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.413027260850299x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL cal(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += cal(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << cal(N) - ans[i] - cal(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

ll cal(int x) {

	return 1ll * x*(x - 1) / 2 + x;

}

ll ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

int main() {

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)scanf("%d", &c[i]);

	for (int i = 1; i < n; i++) {

		int u, v;

		scanf("%d%d", &u, &v);

		G[u].push_back(v);

		G[v].push_back(u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		printf("%lld\n", cal(n) - ans[i] - cal(n - cnt[i]));

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.369861794468824x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// 

// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL count(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += count(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << count(N) - ans[i] - count(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

ll cal(int x) {

	return 1ll * x*(x+1)/2;

}

ll ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

int main() {

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)scanf("%d", &c[i]);

	for (int i = 1; i < n; i++) {

		int u, v;

		scanf("%d%d", &u, &v);

		G[u].push_back(v);

		G[v].push_back(u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		printf("%lld\n", cal(n) - ans[i] - cal(n - cnt[i]));

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.369429608176978x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// 

// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL count(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += count(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << count(N) - ans[i] - count(N-cnt[i]) << endl;

	}

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N = 2e5 + 10;

int n, c[N], cnt[N], siz[N];

inline ll cal(int x) {

	return 1ll * x*(x+1)/2;

}

ll ans[N];

vector<int>G[N];

	void dfs(int v, int fa) {

		int tmp = cnt[c[v]];

		siz[v] = 1;

		for(int u:G[v]) {

			if(u==fa) continue;

			cnt[c[v]] = 0;

			dfs(u, v);

			siz[v] += siz[u];

			ans[c[v]]+=cal(siz[u]-cnt[c[v]]);

		}

		cnt[c[v]] = tmp + siz[v];

	}

int main() {

	scanf("%d", &n);

	for (int i = 1; i <= n; i++)scanf("%d", &c[i]);

	for (int i = 1; i < n; i++) {

		int u, v;

		scanf("%d%d", &u, &v);

		G[u].push_back(v);

		G[v].push_back(u);

	}

	dfs(1, 0);

	for (int i = 1; i <= n; i++) {

		printf("%lld\n", cal(n) - ans[i] - cal(n - cnt[i]));

	}

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 6.369930095292311x):


#include<iostream>

#include<vector>

using namespace std;

#define LL	long long

const int MAXN = 2e5+10;



int N;

int c[MAXN];

//vector<int> G[MAXN];

int tot = 0;

int head[MAXN], Next[2*MAXN], to[2*MAXN];



// 

// sub[i]: 顶点i下子树顶点的个数

int sub[MAXN];

// cnt[i]: 颜色为i的顶点下子树顶点的个数

int cnt[MAXN]; 

// ans[i]: 颜色为i的顶点下不经过颜色i的顶点数

LL ans[MAXN];



// 一开始起名count结果和c++ count()冲突，调试了半天, md

inline LL count(int n) {

	// C(n,2) + n

	return 1LL*n*(n+1)/2;

}



void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int i=head[v]; i; i=Next[i]) {

		int u = to[i];

		if(u == fa) continue;

		cnt[c[v]] = 0;	// 置0重新计数

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]] += count(sub[u] - cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

inline void add(int a, int b) {

	++tot;

	Next[tot] = head[a];

	to[tot] = b;

	head[a] = tot;

}



/*

void dfs(int v, int fa) {

	int tmp = cnt[c[v]];

	sub[v] = 1;

	for(int u:G[v]) {

		if(u==fa) continue;

		cnt[c[v]] = 0;

		dfs(u, v);

		sub[v] += sub[u];

		ans[c[v]]+=cal(sub[u]-cnt[c[v]]);

	}

	cnt[c[v]] = tmp + sub[v];

}

* */



int main() {

	std::ios::sync_with_stdio(false);

	cin>>N;

	for(int i=1; i<=N; i++) {

		cin >> c[i];

	}

	int a, b;

	for(int i=1; i<N; i++) {

		cin>>a>>b;

	

		add(a, b);

		add(b, a);

		

		//G[a].push_back(b);

		//G[b].push_back(a);

	}



	//dfs1(1, 0);

	dfs(1, 0);

	for(int i=1; i<=N; i++) {

		cout << count(N) - ans[i] - count(N-cnt[i]) << endl;

	}

	return 0;

}