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 4
output
Copy
10 9 3 4
input
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 13
output
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;
}