codeforces 600E . 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.
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.
Print n integers — the sums of dominating colours for each vertex.
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 思路:
对每个点建线段树在线段树上当前点的权值下标+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 (线段树合并)的更多相关文章
- CF600E:Lomsat gelral(线段树合并)
Description 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. Input 第一行一个$n$.第二行$n$个数字是$c[i]$.后面$n-1$ ...
- CodeForces600E Lomsat gelral 线段树合并
从树上启发式合并搜出来的题 然而看着好像线段树合并就能解决??? 那么就用线段树合并解决吧 维护\(max, sum\)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可 复杂度\(O(n \ ...
- CF600E Lomsat gelral——线段树合并/dsu on tree
题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
- Codeforces 600E Lomsat gelral (树上启发式合并)
题目链接 Lomsat gelral 占坑……等深入理解了再来补题解…… #include <bits/stdc++.h> using namespace std; #define rep ...
- codeforces 600E. Lomsat gelral 启发式合并
题目链接 给一颗树, 每个节点有初始的颜色值. 1为根节点.定义一个节点的值为, 它的子树中出现最多的颜色的值, 如果有多种颜色出现的次数相同, 那么值为所有颜色的值的和. 每一个叶子节点是一个map ...
- Codeforces 600E. Lomsat gelral(Dsu on tree学习)
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
- Codeforces 600E Lomsat gelral(dsu on tree)
dsu on tree板子题.这个trick保证均摊O(nlogn)的复杂度,要求资瓷O(1)将一个元素插入集合,清空集合时每个元素O(1)删除.(当然log的话就变成log^2了) 具体的,每次先遍 ...
- codeforces 600E Lomsat gelral
题面:codeforces600E 学习一下$dsu \ on \ tree$.. 这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$. 主要操作是:我们先把整棵树链剖一下,然后每次 ...
随机推荐
- js中布尔值为false的六种情况
下面6种值转化为布尔值时为false,其他转化都为true 1.undefined(未定义,找不到值时出现) 2.null(代表空值) 3.false(布尔值的false,字符串"false ...
- from bs4 import BeautifulSoup 报错
一: BeautifulSoup的安装: 下载地址:https://www.crummy.com/software/BeautifulSoup/bs4/download/4.6/ 下载后,解压缩,然后 ...
- AtCoder Beginner Contest 122 D - We Like AGC (DP)
D - We Like AGC Time Limit: 2 sec / Memory Limit: 1024 MB Score : 400400 points Problem Statement Yo ...
- UITableView套UITableView数据刷新
https://www.jianshu.com/p/ee4b2bd54d08 网上关于tableview嵌套tableview的文章很多,纵览很多后发现有两点没有满足需求 把两个tableview放在 ...
- 线程中的samaphore信号量及event事件
一.信号量 samaphore: 在程序中意思为同时允许几个线程运行,比如我们去水上乐园的滑梯玩时,有四个滑梯,每一个滑梯上当没有人在中间玩滑下去时才允许上人,四个滑梯1,2,3,4,同时最多四个人, ...
- Eclipse External Tool Configration Notepad++
Location: C:\Program Files\Notepad++\notepad++.exe Arguments: ${resource_loc}
- opencv2\flann\matrix.h(69): error C2059: 语法错误:“,”
在提示错误的matrix.h头文件中,修改一下,在free前加上_ ,即FLANN_DEPRECATED void _free() .
- IdentityServer4【Introduction】之包和项目构建
包和项目构建 IdentityServer包含了以下的nuget包: IdentityServer4 nuget | github 这个包包含了IdentityServer核心的组成部分,有对象模型, ...
- [转帖]Vim 编辑器底端 [noeol], [dos] 的含义
Vim 编辑器底端 [noeol], [dos] 的含义 2012年11月28日 23:13:04 strongwangjiawei 阅读数:15484 https://blog.csdn.net/s ...
- Java 多线程概述
几乎所有的操作系统都支持同时运行多个任务,一 个任务通常就是一个程序,每个运行中的程序就是一个进程.当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程. 线程和进程 几乎所有的 ...