E. Lomsat gelral
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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
Copy
4 1 2 3 4 1 2 2 3 2 4output
Copy
10 9 3 4input
Copy
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 13output
Copy
6 5 4 3 2 3 3 1 1 3 2 2 1 2 3题意:
给出一棵树和每个结点的颜色,求以 i 为根节点的子树中最多的颜色数量和
dsu on tree的板子题,讲解:https://www.cnblogs.com/zwfymqz/p/9683124.html
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 998244353; const int N = 1e5 + 10; int col[N], son[N], cnt[N], siz[N], Son, Mx; ll ans[N], sum; vector<int> mp[N]; void init() { sum = 0; memset(son, 0, sizeof(son)); memset(cnt, 0, sizeof(cnt)); memset(siz, 0, sizeof(siz)); } void dfs(int u, int fa) { siz[u] = 1; int sz = mp[u].size(); for(int i = 0; i < sz; ++i) { int v = mp[u][i]; if(v == fa) continue; dfs(v, u); siz[u] += siz[v]; if(siz[v] > siz[son[u]]) son[u] = v; } } void add(int u, int fa, int val) { cnt[col[u]] += val; if(cnt[col[u]] > Mx) { Mx = cnt[col[u]]; sum = col[u]; } else if(cnt[col[u]] == Mx) sum += 1ll * col[u]; int sz = mp[u].size(); for(int i = 0; i < sz; ++i) { int v = mp[u][i]; if(v == fa || v == Son) continue; add(v, u, val); } } void dfs2(int u, int fa, int op) { int sz = mp[u].size(); for(int i = 0; i < sz; ++i) { int v = mp[u][i]; if(v == fa) continue; if(v != son[u]) dfs2(v, u, 0); } if(son[u]) { dfs2(son[u], u, 1); Son = son[u]; } add(u, fa, 1); Son = 0; ans[u] = sum; if(!op) { add(u, fa, -1); sum = 0; Mx = 0; } } int main() { int n, u, v; while(~scanf("%d", &n)) { init(); for(int i = 1; i <= n; ++i) mp[i].clear(); for(int i = 1; i <= n; ++i) scanf("%d", &col[i]); for(int i = 1; i < n; ++i) { scanf("%d%d", &u, &v); mp[u].push_back(v); mp[v].push_back(u); } dfs(1, 0); dfs2(1, 0, 0); for(int i = 1; i <= n; ++i) { if(i > 1) printf(" "); printf("%lld", ans[i]); } printf("\n"); } return 0; }