#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 100005;
int n;
int color[MAXN];
vector<int> adj[MAXN];
bool is_centroid[MAXN];
int sz[MAXN];
int freq[MAXN], freq_b[MAXN], cnt[MAXN];
long long SumFreq, SumFreq_b;
long long ans[MAXN];
// Tính kích thước các cây con
void get_sizes(int u, int p) {
sz[u] = 1;
for (int v : adj[u]) {
if (v != p && !is_centroid[v]) {
get_sizes(v, u);
sz[u] += sz[v];
}
}
}
// Tìm đỉnh trọng tâm (Centroid)
int get_centroid(int u, int p, int total) {
for (int v : adj[u]) {
if (v != p && !is_centroid[v] && sz[v] > total / 2) {
return get_centroid(v, u, total);
}
}
return u;
}
// Tính kích thước tương đối so với C và mảng freq toàn cục cho Centroid C
void get_sz_and_freq(int u, int p) {
sz[u] = 1;
cnt[color[u]]++;
bool first = (cnt[color[u]] == 1);
for (int v : adj[u]) {
if (v != p && !is_centroid[v]) {
get_sz_and_freq(v, u);
sz[u] += sz[v];
}
}
if (first) {
freq[color[u]] += sz[u];
SumFreq += sz[u];
}
cnt[color[u]]--;
}
// Tính mảng freq_b riêng cho nhánh con
void get_freq_b(int u, int p) {
cnt[color[u]]++;
bool first = (cnt[color[u]] == 1);
for (int v : adj[u]) {
if (v != p && !is_centroid[v]) {
get_freq_b(v, u);
}
}
if (first) {
freq_b[color[u]] += sz[u];
SumFreq_b += sz[u];
}
cnt[color[u]]--;
}
// Duyệt cây trong nhánh để cộng dồn kết quả vào ans[u]
void solve_branch(int u, int p, long long sum_freq, long long sum_freq_b, int path_len, int tot_nodes, int sz_root_b) {
cnt[color[u]]++;
bool first = (cnt[color[u]] == 1);
if (first) {
sum_freq += freq[color[u]];
sum_freq_b += freq_b[color[u]];
path_len++;
}
// Áp dụng công thức đóng góp của các đỉnh nằm ngoài nhánh hiện tại
ans[u] += 1LL * path_len * (tot_nodes - sz_root_b) + SumFreq - SumFreq_b - sum_freq + sum_freq_b;
for (int v : adj[u]) {
if (v != p && !is_centroid[v]) {
solve_branch(v, u, sum_freq, sum_freq_b, path_len, tot_nodes, sz_root_b);
}
}
cnt[color[u]]--;
}
// Xóa trạng thái của mảng tần số (tránh dùng memset toàn bộ để đảm bảo O(N log N))
void clear_freq_b(int u, int p) {
freq_b[color[u]] = 0;
for (int v : adj[u]) {
if (v != p && !is_centroid[v]) {
clear_freq_b(v, u);
}
}
}
void clear_freq(int u, int p) {
freq[color[u]] = 0;
for (int v : adj[u]) {
if (v != p && !is_centroid[v]) {
clear_freq(v, u);
}
}
}
// Quá trình Centroid Decomposition
void decompose(int u) {
get_sizes(u, 0);
int total = sz[u];
int C = get_centroid(u, 0, total);
// Bước 1: Khởi tạo dữ liệu liên quan đến C
SumFreq = 0;
get_sz_and_freq(C, 0);
ans[C] += SumFreq;
// Bước 2: Duyệt từng nhánh con nối với C
for (int root_b : adj[C]) {
if (!is_centroid[root_b]) {
SumFreq_b = 0;
// Màu của đỉnh Centroid C luôn thuộc mọi đường đi trong thành phần liên thông
cnt[color[C]]++;
freq_b[color[C]] += sz[root_b];
SumFreq_b += sz[root_b];
get_freq_b(root_b, C);
long long init_sum_freq = freq[color[C]];
long long init_sum_freq_b = freq_b[color[C]];
// Tính toán và update mảng ans cho tất cả các đỉnh nhánh hiện tại
solve_branch(root_b, C, init_sum_freq, init_sum_freq_b, 1, sz[C], sz[root_b]);
cnt[color[C]]--;
// Xóa bộ đệm tần số riêng biệt của nhánh đó
clear_freq_b(root_b, C);
freq_b[color[C]] = 0;
}
}
clear_freq(C, 0);
is_centroid[C] = true;
// Phân rã đệ quy trên các thành phần liên thông còn lại
for (int v : adj[C]) {
if (!is_centroid[v]) {
decompose(v);
}
}
}
int main() {
// Tối ưu I/O cho C++
ios_base::sync_with_stdio(false);
cin.tie(NULL);
if (!(cin >> n)) return 0;
for (int i = 1; i <= n; i++) {
cin >> color[i];
}
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
decompose(1);
for (int i = 1; i <= n; i++) {
cout << ans[i] << (i == n ? "" : " ");
}
cout << "\n";
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmNvbnN0IGludCBNQVhOID0gMTAwMDA1OwoKaW50IG47CmludCBjb2xvcltNQVhOXTsKdmVjdG9yPGludD4gYWRqW01BWE5dOwpib29sIGlzX2NlbnRyb2lkW01BWE5dOwppbnQgc3pbTUFYTl07CgppbnQgZnJlcVtNQVhOXSwgZnJlcV9iW01BWE5dLCBjbnRbTUFYTl07CmxvbmcgbG9uZyBTdW1GcmVxLCBTdW1GcmVxX2I7CmxvbmcgbG9uZyBhbnNbTUFYTl07CgovLyBUw61uaCBrw61jaCB0aMaw4bubYyBjw6FjIGPDonkgY29uCnZvaWQgZ2V0X3NpemVzKGludCB1LCBpbnQgcCkgewogICAgc3pbdV0gPSAxOwogICAgZm9yIChpbnQgdiA6IGFkalt1XSkgewogICAgICAgIGlmICh2ICE9IHAgJiYgIWlzX2NlbnRyb2lkW3ZdKSB7CiAgICAgICAgICAgIGdldF9zaXplcyh2LCB1KTsKICAgICAgICAgICAgc3pbdV0gKz0gc3pbdl07CiAgICAgICAgfQogICAgfQp9CgovLyBUw6xtIMSR4buJbmggdHLhu41uZyB0w6JtIChDZW50cm9pZCkKaW50IGdldF9jZW50cm9pZChpbnQgdSwgaW50IHAsIGludCB0b3RhbCkgewogICAgZm9yIChpbnQgdiA6IGFkalt1XSkgewogICAgICAgIGlmICh2ICE9IHAgJiYgIWlzX2NlbnRyb2lkW3ZdICYmIHN6W3ZdID4gdG90YWwgLyAyKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRfY2VudHJvaWQodiwgdSwgdG90YWwpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiB1Owp9CgovLyBUw61uaCBrw61jaCB0aMaw4bubYyB0xrDGoW5nIMSR4buRaSBzbyB24bubaSBDIHbDoCBt4bqjbmcgZnJlcSB0b8OgbiBj4bulYyBjaG8gQ2VudHJvaWQgQwp2b2lkIGdldF9zel9hbmRfZnJlcShpbnQgdSwgaW50IHApIHsKICAgIHN6W3VdID0gMTsKICAgIGNudFtjb2xvclt1XV0rKzsKICAgIGJvb2wgZmlyc3QgPSAoY250W2NvbG9yW3VdXSA9PSAxKTsKICAgIGZvciAoaW50IHYgOiBhZGpbdV0pIHsKICAgICAgICBpZiAodiAhPSBwICYmICFpc19jZW50cm9pZFt2XSkgewogICAgICAgICAgICBnZXRfc3pfYW5kX2ZyZXEodiwgdSk7CiAgICAgICAgICAgIHN6W3VdICs9IHN6W3ZdOwogICAgICAgIH0KICAgIH0KICAgIGlmIChmaXJzdCkgewogICAgICAgIGZyZXFbY29sb3JbdV1dICs9IHN6W3VdOwogICAgICAgIFN1bUZyZXEgKz0gc3pbdV07CiAgICB9CiAgICBjbnRbY29sb3JbdV1dLS07Cn0KCi8vIFTDrW5oIG3huqNuZyBmcmVxX2IgcmnDqm5nIGNobyBuaMOhbmggY29uCnZvaWQgZ2V0X2ZyZXFfYihpbnQgdSwgaW50IHApIHsKICAgIGNudFtjb2xvclt1XV0rKzsKICAgIGJvb2wgZmlyc3QgPSAoY250W2NvbG9yW3VdXSA9PSAxKTsKICAgIGZvciAoaW50IHYgOiBhZGpbdV0pIHsKICAgICAgICBpZiAodiAhPSBwICYmICFpc19jZW50cm9pZFt2XSkgewogICAgICAgICAgICBnZXRfZnJlcV9iKHYsIHUpOwogICAgICAgIH0KICAgIH0KICAgIGlmIChmaXJzdCkgewogICAgICAgIGZyZXFfYltjb2xvclt1XV0gKz0gc3pbdV07CiAgICAgICAgU3VtRnJlcV9iICs9IHN6W3VdOwogICAgfQogICAgY250W2NvbG9yW3VdXS0tOwp9CgovLyBEdXnhu4d0IGPDonkgdHJvbmcgbmjDoW5oIMSR4buDIGPhu5luZyBk4buTbiBr4bq/dCBxdeG6oyB2w6BvIGFuc1t1XQp2b2lkIHNvbHZlX2JyYW5jaChpbnQgdSwgaW50IHAsIGxvbmcgbG9uZyBzdW1fZnJlcSwgbG9uZyBsb25nIHN1bV9mcmVxX2IsIGludCBwYXRoX2xlbiwgaW50IHRvdF9ub2RlcywgaW50IHN6X3Jvb3RfYikgewogICAgY250W2NvbG9yW3VdXSsrOwogICAgYm9vbCBmaXJzdCA9IChjbnRbY29sb3JbdV1dID09IDEpOwogICAgaWYgKGZpcnN0KSB7CiAgICAgICAgc3VtX2ZyZXEgKz0gZnJlcVtjb2xvclt1XV07CiAgICAgICAgc3VtX2ZyZXFfYiArPSBmcmVxX2JbY29sb3JbdV1dOwogICAgICAgIHBhdGhfbGVuKys7CiAgICB9CgogICAgLy8gw4FwIGThu6VuZyBjw7RuZyB0aOG7qWMgxJHDs25nIGfDs3AgY+G7p2EgY8OhYyDEkeG7iW5oIG7hurFtIG5nb8OgaSBuaMOhbmggaGnhu4duIHThuqFpCiAgICBhbnNbdV0gKz0gMUxMICogcGF0aF9sZW4gKiAodG90X25vZGVzIC0gc3pfcm9vdF9iKSArIFN1bUZyZXEgLSBTdW1GcmVxX2IgLSBzdW1fZnJlcSArIHN1bV9mcmVxX2I7CgogICAgZm9yIChpbnQgdiA6IGFkalt1XSkgewogICAgICAgIGlmICh2ICE9IHAgJiYgIWlzX2NlbnRyb2lkW3ZdKSB7CiAgICAgICAgICAgIHNvbHZlX2JyYW5jaCh2LCB1LCBzdW1fZnJlcSwgc3VtX2ZyZXFfYiwgcGF0aF9sZW4sIHRvdF9ub2Rlcywgc3pfcm9vdF9iKTsKICAgICAgICB9CiAgICB9CgogICAgY250W2NvbG9yW3VdXS0tOwp9CgovLyBYw7NhIHRy4bqhbmcgdGjDoWkgY+G7p2EgbeG6o25nIHThuqduIHPhu5EgKHRyw6FuaCBkw7luZyBtZW1zZXQgdG/DoG4gYuG7mSDEkeG7gyDEkeG6o20gYuG6o28gTyhOIGxvZyBOKSkKdm9pZCBjbGVhcl9mcmVxX2IoaW50IHUsIGludCBwKSB7CiAgICBmcmVxX2JbY29sb3JbdV1dID0gMDsKICAgIGZvciAoaW50IHYgOiBhZGpbdV0pIHsKICAgICAgICBpZiAodiAhPSBwICYmICFpc19jZW50cm9pZFt2XSkgewogICAgICAgICAgICBjbGVhcl9mcmVxX2IodiwgdSk7CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIGNsZWFyX2ZyZXEoaW50IHUsIGludCBwKSB7CiAgICBmcmVxW2NvbG9yW3VdXSA9IDA7CiAgICBmb3IgKGludCB2IDogYWRqW3VdKSB7CiAgICAgICAgaWYgKHYgIT0gcCAmJiAhaXNfY2VudHJvaWRbdl0pIHsKICAgICAgICAgICAgY2xlYXJfZnJlcSh2LCB1KTsKICAgICAgICB9CiAgICB9Cn0KCi8vIFF1w6EgdHLDrG5oIENlbnRyb2lkIERlY29tcG9zaXRpb24Kdm9pZCBkZWNvbXBvc2UoaW50IHUpIHsKICAgIGdldF9zaXplcyh1LCAwKTsKICAgIGludCB0b3RhbCA9IHN6W3VdOwogICAgaW50IEMgPSBnZXRfY2VudHJvaWQodSwgMCwgdG90YWwpOwoKICAgIC8vIELGsOG7m2MgMTogS2jhu59pIHThuqFvIGThu68gbGnhu4d1IGxpw6puIHF1YW4gxJHhur9uIEMKICAgIFN1bUZyZXEgPSAwOwogICAgZ2V0X3N6X2FuZF9mcmVxKEMsIDApOwogICAgYW5zW0NdICs9IFN1bUZyZXE7CgogICAgLy8gQsaw4bubYyAyOiBEdXnhu4d0IHThu6tuZyBuaMOhbmggY29uIG7hu5FpIHbhu5tpIEMKICAgIGZvciAoaW50IHJvb3RfYiA6IGFkaltDXSkgewogICAgICAgIGlmICghaXNfY2VudHJvaWRbcm9vdF9iXSkgewogICAgICAgICAgICBTdW1GcmVxX2IgPSAwOwoKICAgICAgICAgICAgLy8gTcOgdSBj4bunYSDEkeG7iW5oIENlbnRyb2lkIEMgbHXDtG4gdGh14buZYyBt4buNaSDEkcaw4budbmcgxJFpIHRyb25nIHRow6BuaCBwaOG6p24gbGnDqm4gdGjDtG5nCiAgICAgICAgICAgIGNudFtjb2xvcltDXV0rKzsKICAgICAgICAgICAgZnJlcV9iW2NvbG9yW0NdXSArPSBzeltyb290X2JdOwogICAgICAgICAgICBTdW1GcmVxX2IgKz0gc3pbcm9vdF9iXTsKCiAgICAgICAgICAgIGdldF9mcmVxX2Iocm9vdF9iLCBDKTsKCiAgICAgICAgICAgIGxvbmcgbG9uZyBpbml0X3N1bV9mcmVxID0gZnJlcVtjb2xvcltDXV07CiAgICAgICAgICAgIGxvbmcgbG9uZyBpbml0X3N1bV9mcmVxX2IgPSBmcmVxX2JbY29sb3JbQ11dOwoKICAgICAgICAgICAgLy8gVMOtbmggdG/DoW4gdsOgIHVwZGF0ZSBt4bqjbmcgYW5zIGNobyB04bqldCBj4bqjIGPDoWMgxJHhu4luaCBuaMOhbmggaGnhu4duIHThuqFpCiAgICAgICAgICAgIHNvbHZlX2JyYW5jaChyb290X2IsIEMsIGluaXRfc3VtX2ZyZXEsIGluaXRfc3VtX2ZyZXFfYiwgMSwgc3pbQ10sIHN6W3Jvb3RfYl0pOwoKICAgICAgICAgICAgY250W2NvbG9yW0NdXS0tOwoKICAgICAgICAgICAgLy8gWMOzYSBi4buZIMSR4buHbSB04bqnbiBz4buRIHJpw6puZyBiaeG7h3QgY+G7p2EgbmjDoW5oIMSRw7MKICAgICAgICAgICAgY2xlYXJfZnJlcV9iKHJvb3RfYiwgQyk7CiAgICAgICAgICAgIGZyZXFfYltjb2xvcltDXV0gPSAwOwogICAgICAgIH0KICAgIH0KCiAgICBjbGVhcl9mcmVxKEMsIDApOwogICAgaXNfY2VudHJvaWRbQ10gPSB0cnVlOwoKICAgIC8vIFBow6JuIHLDoyDEkeG7hyBxdXkgdHLDqm4gY8OhYyB0aMOgbmggcGjhuqduIGxpw6puIHRow7RuZyBjw7JuIGzhuqFpCiAgICBmb3IgKGludCB2IDogYWRqW0NdKSB7CiAgICAgICAgaWYgKCFpc19jZW50cm9pZFt2XSkgewogICAgICAgICAgICBkZWNvbXBvc2Uodik7CiAgICAgICAgfQogICAgfQp9CgppbnQgbWFpbigpIHsKICAgIC8vIFThu5FpIMawdSBJL08gY2hvIEMrKwogICAgaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgICBjaW4udGllKE5VTEwpOwoKICAgIGlmICghKGNpbiA+PiBuKSkgcmV0dXJuIDA7CgogICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKSB7CiAgICAgICAgY2luID4+IGNvbG9yW2ldOwogICAgfQoKICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgaW50IHUsIHY7CiAgICAgICAgY2luID4+IHUgPj4gdjsKICAgICAgICBhZGpbdV0ucHVzaF9iYWNrKHYpOwogICAgICAgIGFkalt2XS5wdXNoX2JhY2sodSk7CiAgICB9CgogICAgZGVjb21wb3NlKDEpOwoKICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IG47IGkrKykgewogICAgICAgIGNvdXQgPDwgYW5zW2ldIDw8IChpID09IG4gPyAiIiA6ICIgIik7CiAgICB9CiAgICBjb3V0IDw8ICJcbiI7CgogICAgcmV0dXJuIDA7Cn0K