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
4
1 2 3 4
1 2
2 3
2 4
10 9 3 4
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
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? '\n':' '); 63 64 return 0; 65 }