CF600E Lomsat gelral (启发式合并)

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 ≤ 105) — the number of vertices in the tree.

The second line contains n integers 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


题解:题意就是定义一个节点的优势点为他的子树中出现次数最多的数字,(可能会有多个优势点),让你求每一个点的优势点的和;
可以用map记录每一个点的各个优势点,记录每点的子树中每个数字出现的次数,然后dfs。
参考代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define clr(a,val) memset(a,val,sizeof(a))
 4 #define pb push_back
 5 #define fi first
 6 #define se second
 7 typedef long long ll;
 8 const int maxn=1e5+10;
 9 int n,cnt;
10 int col[maxn],head[maxn],dy[maxn];
11 ll ans[maxn];
12 struct Edge{
13     int to,nxt;
14 } edge[maxn<<1];
15 map<int,int> mp[maxn];
16 map<int,ll> sum[maxn];
17 map<int,int>::iterator it1,it2;
18 inline int read()
19 {
20     int x=0,f=1;char ch=getchar();
21     while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();} 
22     while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
23     return x*f;
24 }
25 
26 inline void addedge(int u,int v)
27 {
28     edge[cnt].to=v;
29     edge[cnt].nxt=head[u];
30     head[u]=cnt++;
31 }
32 
33 inline void dfs(int u,int fa)
34 {
35     for(int e=head[u];~e;e=edge[e].nxt)
36     {
37         int v=edge[e].to;
38         if(v==fa) continue;
39         dfs(v,u);
40         if(mp[dy[u]].size()<mp[dy[v]].size()) swap(dy[u],dy[v]);
41         for(it1=mp[dy[v]].begin();it1!=mp[dy[v]].end();it1++)
42         {
43             sum[dy[u]][mp[dy[u]][(*it1).fi]]-=(*it1).fi;
44             mp[dy[u]][(*it1).fi]+=(*it1).se;
45             sum[dy[u]][mp[dy[u]][(*it1).fi]]+=(*it1).fi;
46         }
47     } 
48     ans[u]=(*sum[dy[u]].rbegin()).se;
49 }
50 
51 int main()
52 {
53     n=read();
54     for(int i=1;i<=n;++i) col[i]=read(),dy[i]=i,mp[i][col[i]]=1,sum[i][1]=col[i];
55     int u,v;cnt=0;clr(head,-1);
56     for(int i=1;i<n;++i) 
57     {
58         u=read();v=read();
59         addedge(u,v);addedge(v,u);
60     }
61     dfs(1,0);
62     for(int i=1;i<=n;++i) printf("%lld%c",ans[i],i==n? '
':' ');
63     
64     return 0;
65 }
View Code
原文地址:https://www.cnblogs.com/csushl/p/10293301.html