You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour.
Let’s call colour c dominating in the subtree of vertex v if there are no other colours that appear in the subtree of vertex v more times than colour c. So it’s possible that two or more colours will be dominating in the subtree of some vertex.
The subtree of vertex v is the vertex v and all other vertices that contains vertex v in each path to the root.
For each vertex v find the sum of all dominating colours in the subtree of vertex v.
Input
The first line contains integer
n
(
1
≤
n
≤
1
0
5
n (1 ≤ n ≤ 10^5
n(1 ≤ n ≤ 105 $) — the number of vertices in the tree.
The second line contains n integers c i ( 1 < = c i < = n ) c_i(1<=c_i<=n) ci(1<=ci<=n), ci — the colour of the i-th vertex.
Each of the next n - 1 lines contains two integers xj, yj (1 ≤ xj, yj ≤ n) — the edge of the tree. The first vertex is the root of the tree.
Output
Print n integers — the sums of dominating colours for each vertex.
Examples
input
4
1 2 3 4
1 2
2 3
2 4
output
10 9 3 4
input
15
1 2 3 1 2 3 3 1 1 3 2 2 1 2 3
1 2
1 3
1 4
1 14
1 15
2 5
2 6
2 7
3 8
3 9
3 10
4 11
4 12
4 13
output
6 5 4 3 2 3 3 1 1 3 2 2 1 2 3
这题比较牛逼,我第一次接触这种类型的题,其实算是一种启发式合并的问题,dsu on tree可以解决一类静态树上的问题。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#define ll long long
#define maxx 100005
#define INF 0x7f7f7f7f
using namespace std;
int n;
int head[maxx],to[maxx<<1],_next[maxx<<1];
int edge;
inline void addEdge(int x,int y)
{
to[++edge]=y,_next[edge]=head[x],head[x]=edge;
to[++edge]=x,_next[edge]=head[y],head[y]=edge;
}
//����
int _size[maxx];
int son[maxx];
void dfs1(int u,int fa)
{
_size[u]=1;
int maxson=-1;
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v==fa)continue;
dfs1(v,u);
_size[u]+=_size[v];
if(_size[v]>maxson)
{
son[u]=v;
maxson=_size[v];
}
}
}
int l[maxx],r[maxx],_index;
int a[maxx],b[maxx];
void dfs2(int u,int fa)
{
l[u]=++_index;
a[_index]=b[u];
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v==fa)continue;
dfs2(v,u);
}
r[u]=_index;
}
int cnt[maxx];
ll res=0;
int _max=0;
void del(int u)
{
res=0;
_max=0;
for(int i=l[u];i<=r[u];i++)
cnt[a[i]]=0;
}
void add(int u)
{
for(int i=l[u];i<=r[u];i++)
{
cnt[a[i]]++;
if(cnt[a[i]]>_max)
{
res=a[i];
_max=cnt[a[i]];
}
else if(cnt[a[i]]==_max)res+=a[i];
}
}
ll ans[maxx];
void dfs(int u,int fa)
{
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v==fa)continue;
if(son[u]!=v)
{
dfs(v,u);
del(v);
}
}
if(son[u])dfs(son[u],u);
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v==fa)continue;
if(son[u]!=v)add(v);
}
cnt[b[u]]++;
if(cnt[b[u]]>_max)
{
res=b[u];
_max=cnt[b[u]];
}
else if(cnt[b[u]]==_max)res+=b[u];
ans[u]=res;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",b+i);
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
addEdge(x,y);
}
dfs1(1,0);
dfs2(1,0);
dfs(1,0);
for(int i=1;i<n;i++)
printf("%I64d ",ans[i]);
printf("%I64d\n",ans[n]);
return 0;
}