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.
题意就不说了
思路:
树上启发式合并主要是用来处理子树的值的某些特征,用一个容器去维护就行,上模板
#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn = 1e5+6;
int siz[maxn];
int son[maxn];
int skip[maxn];
int n;
int va[maxn];
int head[maxn];
int tot;
LL ans[maxn];
LL cnt[maxn];
struct node
{
int u,v;
int net;
}E[maxn*2];
void init()
{
memset(head,-1,sizeof(head));
tot = 0;
}
void build(int u,int v)
{
E[tot].u = u;
E[tot].v = v;
E[tot].net = head[u];
head[u] = tot++;
}
void dfs0(int u,int fa)
{
siz[u] = 1;
for(int i = head[u];~i;i = E[i].net){
int v = E[i].v;
if(v==fa){
continue;
}
dfs0(v,u);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v]){
son[u] = v;
}
}
}
LL mx = 0;
LL sum = 0;
void getans(int u,int fa,int vv)
{
cnt[va[u]]+=vv;
if(vv>0&&cnt[va[u]]>mx){
mx = cnt[va[u]];
sum = va[u];
}
else if(vv>0&&cnt[va[u]]==mx){
mx = cnt[va[u]];
sum += va[u];
}
for(int i = head[u];~i;i = E[i].net){
if(E[i].v==fa||skip[E[i].v]) continue;
getans(E[i].v,u,vv);
}
}
void dfs(int u,int fa,int op)
{
// cout<<u<<endl;
for(int i = head[u];~i;i = E[i].net){
int v = E[i].v;
if(v==fa||v==son[u]) continue;
dfs(v,u,0);
}
if(son[u]){
dfs(son[u],u,1);
skip[son[u]] = 1;
}
getans(u,fa,1);
ans[u] = sum;
if(son[u]){
skip[son[u]] = 0;
}
if(op==0){
getans(u,fa,-1);
sum = mx = 0;
}
}
int main()
{
init();
scanf("%d",&n);
for(int i = 1;i<=n;i++){
scanf("%d",&va[i]);
}
for(int i = 0;i<n-1;i++){
int u,v;
scanf("%d%d",&u,&v);
build(u,v);
build(v,u);
}
dfs0(1,0);
dfs(1,0,1);
for(int i = 1;i<=n;i++){
printf("%lld%c",ans[i],i==n?'\n':' ');
}
}