dsu on tree(CF600E Lomsat gelral)
题意
一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和。
dsu on tree
用来解决子树问题
好像不能带修改??
暴力做这个题,就是每次扫一遍子树统计答案
时间\(O(n^2)\)
或者会高级的数据结构解决
空间,编程难度是个挑战
然而\(dsu \ on \ tree\)树上启发式合并则是一个好方法
它通过增加对重儿子子树信息的利用来提高效率
流程:
递归轻儿子
递归重儿子
统计答案
如果该点为它父亲的重儿子,保存信息
否则删除信息
复杂度分析:
每个点被扫到的次数只有它到根的路径上轻边的次数*\(2\)次
也就是\(log\)次
那么总复杂度为空间\(O(n)\),时间\(O(nlogn)\)
该题代码
# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
const int maxn(1e5 + 5);
int n, first[maxn], cnt, col[maxn], size[maxn], son[maxn], vis[maxn], num[maxn], mx;
ll sum[maxn], ans[maxn];
struct Edge{
int to, next;
} edge[maxn << 1];
IL void Add(RG int u, RG int v){
edge[cnt] = (Edge){v, first[u]}, first[u] = cnt++;
}
IL void Dfs(RG int u, RG int ff){
size[u] = 1;
for(RG int e = first[u]; e != -1; e = edge[e].next){
RG int v = edge[e].to;
if(v != ff){
Dfs(v, u);
size[u] += size[v];
if(size[v] > size[son[u]]) son[u] = v;
}
}
}
IL void Update(RG int u, RG int ff, RG int val){
sum[num[col[u]]] -= col[u];
num[col[u]] += val;
sum[num[col[u]]] += col[u];
if(val > 0) mx = max(mx, num[col[u]]);
else while(mx && !sum[mx]) --mx;
for(RG int e = first[u]; e != -1; e = edge[e].next)
if(edge[e].to != ff && !vis[edge[e].to]) Update(edge[e].to, u, val);
}
IL void Solve(RG int u, RG int ff, RG int op){
size[u] = 1;
for(RG int e = first[u]; e != -1; e = edge[e].next)
if(edge[e].to != ff && edge[e].to != son[u]) Solve(edge[e].to, u, 0);
if(son[u]) Solve(son[u], u, 1), vis[son[u]] = 1;
Update(u, ff, 1), vis[son[u]] = 0;
ans[u] = sum[mx];
if(!op) Update(u, ff, -1);
}
int main(){
n = Input();
for(RG int i = 1; i <= n; ++i) col[i] = Input(), first[i] = -1;
for(RG int i = 1; i < n; ++i){
RG int u = Input(), v = Input();
Add(u, v), Add(v, u);
}
Dfs(1, 0), Solve(1, 0, 1);
for(RG int i = 1; i <= n; ++i) printf("%lld ", ans[i]);
return 0;
}
dsu on tree(CF600E Lomsat gelral)的更多相关文章
- CF600E Lomsat gelral(dsu on tree)
dsu on tree跟冰茶祭有什么关系啊喂 dsu on tree的模板题 思想与解题过程 类似树链剖分的思路 先统计轻儿子的贡献,再统计重儿子的贡献,得出当前节点的答案后再减去轻儿子对答案的贡献 ...
- cf600E. Lomsat gelral(dsu on tree)
题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...
- CF600E Lomsat gelral——线段树合并/dsu on tree
题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...
- CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths
Lomsat gelral 一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和). \(n \le 10^ ...
- [CF600E]Lomsat gelral
题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 线段树合并板子题,没啥难度,注意开long long 不过这题$dsu$ $on$ $tre ...
- CF600E Lomsat gelral 树上启发式合并
题目描述 有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树. 每个结点都有一个颜色,颜色是以编号表示的, \(i\) 号结点的颜色编号为 \(c_i\). 如果一种颜色在以 \(x\) ...
- CF600E Lomsat gelral 【线段树合并】
题目链接 CF600E 题解 容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可 对于每个节点合并一下两个子节点的信息 要注意叶子节点信息的合并和非叶节点信息的合并是不一样的 ...
- CF600E Lomsat gelral (启发式合并)
You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's cal ...
- CF600E Lomsat gelral (dfs序+莫队)
题面 题解 看到网上写了很多DSU和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...
随机推荐
- Rabbitmq 消息对列 生产者与消费者的具体实现 springboot
RabbitMQ 基本介绍 RabbitMQ的设计理念是.只要有接收消息的队列. 邮件就会存放到队列里. 直到订阅人取走. . 如果没有可以接收这个消息的消息队列. 默认是抛弃这个消息的.. 我实现的 ...
- Nginx采用yum安装-Carr
(1)使用yum安装nginx需要包括Nginx的库,安装Nginx的库 #rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx- ...
- eclipse的classpath(build path)和classpaht几种设置的方式
1,默认eclipse有自己的classpath的路径并不是环境变量中配置的classpah. 2,eclipse的classpath每个项目不同,一般是在工作区的当前项目的class下. 2.1,可 ...
- 利用python 学习数据分析 (学习三)
内容学习自: Python for Data Analysis, 2nd Edition 就是这本 纯英文学的很累,对不对取决于百度翻译了 前情提要: 各种方法贴: https://w ...
- nginx负载均衡之入门配置
先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况.那么负载均衡的前提就是要有多台服务器才能实现,也就是两台以上 ...
- Spring Boot 笔记汇总
使用IDEA搭建Spring Boot入门项目 从零开始完整搭建 Spring-Boot 项目开发框架的教程 IDEA通过Maven WebApp archetype 创建Spring boot项目骨 ...
- 【Alpha】Phylab 展示博客
目录 Phylab Alpha 展示博客 一.团队简介 二.项目目标 2.1 典型用户 2.2 功能描述 2.3 用户量 三.项目发布与展示 3.1 新功能 3.2 修复缺陷 3.3 问题与限制 3. ...
- linux常用多线程下载工具
1.axel 下载安装yum install axel 这个软件下载速度实时显示
- 【CSS3】background-origin和background-clip的区别
background-clip 与 background-origin是css3中引入的两个跟元素背景相关的属性,它们有相同的可选值,即border.padding.content三种,而且这两个属性 ...
- Flink初始
flink初始 flink是什么 为什么使用flink flink的基础概念 flink剖析 实例 flink是什么 flink是一个用于有界和无界数据流进行有状态的计算框架. flink提供了不同级 ...