WA#25
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int M=1e5+10;
struct node {
int l,r,v,c;
} tree[M*30];
int ans[M];
vector<int> g[M];
int root[M],tot,n,num[M];
#define mid (l+r)/2
void push_up(int rt) {
if(tree[tree[rt].l].v == tree[tree[rt].r].v) {
tree[rt].v = tree[tree[rt].l].v;
tree[rt].c = tree[tree[rt].l].c + tree[tree[rt].r].c;
} else if(tree[tree[rt].l].v > tree[tree[rt].r].v) {
tree[rt].v = tree[tree[rt].l].v;
tree[rt].c = tree[tree[rt].l].c;
} else {
tree[rt].v = tree[tree[rt].r].v;
tree[rt].c = tree[tree[rt].r].c;
}
return;
}
int _merge(int rt1,int rt2,int l,int r) {
if(!rt1) return rt2;
if(!rt2) return rt1;
if(l==r) {
tree[rt1].v+=tree[rt2].v;
tree[rt1].c=l;
return rt1;
}
tree[rt1].l=_merge(tree[rt1].l,tree[rt2].l,l,mid);
tree[rt1].r=_merge(tree[rt1].r,tree[rt2].r,mid+1,r);
push_up(rt1);
return rt1;
}
int update(int rt,int l,int r,int p,int v) {
if(rt==0) rt=++tot;
if(l==r) {
tree[rt].v+=v;
tree[rt].c=l;
return rt;
}
if(p<=mid) tree[rt].l=update(tree[rt].l,l,mid,p,v);
else tree[rt].r=update(tree[rt].r,mid+1,r,p,v);
push_up(rt);
return rt;
}
void DFS(int now,int lst) {
for(auto v:g[now]) {
if(v!=lst) {
DFS(v,now);
root[now]=_merge(root[now],root[v],1,n);
}
}
ans[now]=tree[root[now]].c;
return;
}
int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",&num[i]);
root[i]=update(root[i],1,n,num[i],1);
}
for(int i=1,u,v; i<n; i++) {
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("%d ",ans[i]);
}
return 0;
}