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

思路:

对每个点建线段树在线段树上当前点的权值下标+1,每个点与父节点进行线段树合并,这样对树dfs一遍就可以求出所有的值了。

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mid ll m = (l + r) >> 1
const ll M = 1e5 + ; struct node{
ll ans,sum;
}tr[M*]; struct node1{
ll to,next;
}e[M<<];
ll cnt,head[M],idx,ls[M*],rs[M*],root[M],a[M],ans[M]; void add(ll u,ll v){
e[++cnt].to = v;e[cnt].next = head[u];head[u] = cnt;
} void pushup(ll rt){
if(tr[ls[rt]].sum > tr[rs[rt]].sum){
tr[rt].sum = tr[ls[rt]].sum;
tr[rt].ans = tr[ls[rt]].ans;
}
else if(tr[ls[rt]].sum == tr[rs[rt]].sum){
tr[rt].sum = tr[ls[rt]].sum;
tr[rt].ans = tr[rs[rt]].ans + tr[ls[rt]].ans;
}
else{
tr[rt].sum = tr[rs[rt]].sum;
tr[rt].ans = tr[rs[rt]].ans;
}
} void update(ll p,ll c,ll l,ll r,ll &rt){
if(!rt) rt = ++idx;
if(l == r){
tr[rt].sum += c;
tr[rt].ans = l;
return ;
}
mid;
if(p <= m) update(p,c,l,m,ls[rt]);
else update(p,c,m+,r,rs[rt]);
pushup(rt);
} ll Merge(ll x,ll y,ll l,ll r){
if(!x) return y;
if(!y) return x;
if(l == r){
tr[x].sum += tr[y].sum;
tr[x].ans = l;
return x;
}
mid;
ls[x] = Merge(ls[x],ls[y],l,m);
rs[x] = Merge(rs[x],rs[y],m+,r);
pushup(x);
return x;
} void dfs(ll u,ll fa){
for(ll i = head[u];i;i=e[i].next){
ll v = e[i].to;
if(v == fa) continue;
dfs(v,u);
Merge(root[u],root[v],,M);
}
update(a[u],,,M,root[u]);
ans[u] = tr[root[u]].ans;
} int main()
{
ll n,u,v;
scanf("%lld",&n);
for(ll i = ;i <= n;i ++){
scanf("%lld",&a[i]);
root[i] = i;
idx++;
}
for(ll i = ;i < n;i ++){
scanf("%lld%lld",&u,&v);
add(u,v); add(v,u);
}
dfs(,);
for(ll i = ;i <= n;i ++){
printf("%lld ",ans[i]);
}
return ; }

codeforces 600E . Lomsat gelral (线段树合并)的更多相关文章

  1. CF600E:Lomsat gelral(线段树合并)

    Description 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. Input 第一行一个$n$.第二行$n$个数字是$c[i]$.后面$n-1$ ...

  2. CodeForces600E Lomsat gelral 线段树合并

    从树上启发式合并搜出来的题 然而看着好像线段树合并就能解决??? 那么就用线段树合并解决吧 维护\(max, sum\)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可 复杂度\(O(n \ ...

  3. CF600E Lomsat gelral——线段树合并/dsu on tree

    题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...

  4. Codeforces 600E - Lomsat gelral(树上启发式合并)

    600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...

  5. Codeforces 600E Lomsat gelral (树上启发式合并)

    题目链接 Lomsat gelral 占坑……等深入理解了再来补题解…… #include <bits/stdc++.h> using namespace std; #define rep ...

  6. codeforces 600E. Lomsat gelral 启发式合并

    题目链接 给一颗树, 每个节点有初始的颜色值. 1为根节点.定义一个节点的值为, 它的子树中出现最多的颜色的值, 如果有多种颜色出现的次数相同, 那么值为所有颜色的值的和. 每一个叶子节点是一个map ...

  7. Codeforces 600E. Lomsat gelral(Dsu on tree学习)

    题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...

  8. Codeforces 600E Lomsat gelral(dsu on tree)

    dsu on tree板子题.这个trick保证均摊O(nlogn)的复杂度,要求资瓷O(1)将一个元素插入集合,清空集合时每个元素O(1)删除.(当然log的话就变成log^2了) 具体的,每次先遍 ...

  9. codeforces 600E Lomsat gelral

    题面:codeforces600E 学习一下$dsu \ on \ tree$.. 这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$. 主要操作是:我们先把整棵树链剖一下,然后每次 ...

随机推荐

  1. centos7 关闭selinux

    关闭SeLinux 临时关闭:setenforce 0 永久关闭:vi /etc/selinux/config

  2. 200 ok 几种状态

    浏览器加载资源成功一般会有几种状态 200 ok   ----  从原始服务器请求成功 200 ok from cache    ---- 200 ok from disk cache  ---- 2 ...

  3. PYTHON访问数据库

    PYTHON DB API(规范)框架 可以一次编写同时访问MySql\ Oracle \SQLServer...不同的数据库服务器:统一接口程序的混乱. 1.连接访问:connection(高速路) ...

  4. getQueryStringByName url参数/

    MasterId: (masterIdUrl != null && masterIdUrl != "") ? masterIdUrl : null ClassId: ...

  5. IBM的淘汰之路

    BM曾经在计算领域独领风骚,但是90年被PC产业链上的微软.英特尔等厂商围殴,遭遇最严重的危机; 今天在云计算市场,IBM曾在遭遇同样的危机,这一次不知道它能否安然度过; IBM收购红帽转向混合云,是 ...

  6. Ubuntu18.04更新源

    一.备份/etc/apt/sources.list文件 cd /etc/apt sudo cp sources.list sources.list.old 二.选择国内常用的源 #阿里源 deb ht ...

  7. 注入技术--LSP劫持注入

    1.原理 简单来说,LSP就是一个dll程序. 应用程序通过winsock2进行网络通信时,会调用ws2_32.dll的导出函数,如connect,accept等. 而后端通过LSP实现这些函数的底层 ...

  8. Satis搭建composer私有库(自定义下载目录)

    在我们的日常php开发中需要使用大量的第三方包和类库, 怎么管理是一个问题, 我们用的Yii2框架, 但是并没有把composer用起来, 由于最近更换为docker部署项目, 于是想起来用compo ...

  9. Windows字符集安装

    0. 获取字符集安装文件. 最简单的办法 上msdn i tell you 下载 多语言安装盘. 一般都比较大. 比如: 1. 进入windows10 操作系统. 运行输入: lpksetup 选择安 ...

  10. Eclipse导入工程后出现中文乱码

    Eclipse之所以会出现乱码问题是因为eclipse编辑器选择的编码规则是可变的.一般默认都是UTF-8或者GBK,当从外部导入的一个工程时,如果该工程的编码方式与eclipse中设置的编码方式不同 ...