[Codeforces600E] Lomsat gelral(树上启发式合并)
[Codeforces600E] Lomsat gelral(树上启发式合并)
题面
给出一棵N个点的树,求其所有子树内出现次数最多的颜色编号和。如果多种颜色出现次数相同,那么编号都要算进答案
N≤100000
分析
树上启发式合并,用map记录颜色出现次数,合并的时候更新最多的出现次数和编号和。
注意合并时的下标问题。当我们merge(x,y)的时候,由于是启发式合并,s[x]可能会并到s[y]去,如果我们直接查询s[x],就查不到真正的答案。所以要再建立一个数组id[x],记录x的map合并之后到了哪里
代码
//树上启发式合并
#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<cstring>
#include<vector>
#define maxn 100000
using namespace std;
int n;
int c[maxn+5];
vector<int>E[maxn+5];
int id[maxn+5];
//当我们merge(x,y)的时候,由于是启发式合并,s[x]可能会并到s[y]去
//然后直接查询s[x]就炸了,所以id[x]就是记录x的map合并之后到了哪里
map<int,int>s[maxn+5];
int ans_max[maxn+5];//最多的出现次数
long long ans_cnt[maxn+5];//编号和
long long res[maxn+5];
void merge(int x,int y){
if(s[id[x]].size()<s[id[y]].size()){
swap(id[x],id[y]);
}
int u=id[x],v=id[y];
for(auto it : s[v]){
int val=it.first;
int cnt=it.second;
s[u][val]+=cnt;
if(s[u][val]>ans_max[u]){
ans_max[u]=s[u][val];
ans_cnt[u]=val;
}else if(s[u][val]==ans_max[u]){
ans_cnt[u]+=val;
}
}
}
void dfs(int x,int fa){
for(int y : E[x]){
if(y!=fa){
dfs(y,x);
merge(x,y);
}
}
res[x]=ans_cnt[id[x]];
}
int main(){
int u,v;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
id[i]=i;
s[i][c[i]]=1;
ans_max[i]=1;
ans_cnt[i]=c[i];
}
for(int i=1;i<n;i++){
scanf("%d %d",&u,&v);
E[u].push_back(v);
E[v].push_back(u);
}
dfs(1,0);
for(int i=1;i<=n;i++){
printf("%I64d ",res[i]);
}
}
[Codeforces600E] Lomsat gelral(树上启发式合并)的更多相关文章
- CF EDU - E. Lomsat gelral 树上启发式合并
学习:http://codeforces.com/blog/entry/44351 E. Lomsat gelral 题意: 给定一个以1为根节点的树,每个节点都有一个颜色,问每个节点的子树中,颜色最 ...
- CF 600 E Lomsat gelral —— 树上启发式合并
题目:http://codeforces.com/contest/600/problem/E 看博客:https://blog.csdn.net/blue_kid/article/details/82 ...
- CF600E Lomsat gelral 树上启发式合并
题目描述 有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树. 每个结点都有一个颜色,颜色是以编号表示的, \(i\) 号结点的颜色编号为 \(c_i\). 如果一种颜色在以 \(x\) ...
- 【CF600E】Lomsat gelral——树上启发式合并
(题面来自luogu) 题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. ci <= n <= 1e5 裸题.统计时先扫一遍得到出 ...
- CodeForces600E Lomsat gelral 线段树合并
从树上启发式合并搜出来的题 然而看着好像线段树合并就能解决??? 那么就用线段树合并解决吧 维护\(max, sum\)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可 复杂度\(O(n \ ...
- Codeforces 600 E. Lomsat gelral (dfs启发式合并map)
题目链接:http://codeforces.com/contest/600/problem/E 给你一棵树,告诉你每个节点的颜色,问你以每个节点为根的子树中出现颜色次数最多的颜色编号和是多少. 最容 ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
- 【学习笔记/题解】树上启发式合并/CF600E Lomsat gelral
题目戳我 \(\text{Solution:}\) 树上启发式合并,是对普通暴力的一种优化. 考虑本题,最暴力的做法显然是暴力统计每一次的子树,为了避免其他子树影响,每次统计完子树都需要清空其信息. ...
- 【CF600E】Lomset gelral 题解(树上启发式合并)
题目链接 题目大意:给出一颗含有$n$个结点的树,每个节点有一个颜色.求树中每个子树最多的颜色的编号和. ------------------------- 树上启发式合并(dsu on tree). ...
随机推荐
- python 简易小爬虫
此脚本用于爬站点的下载链接,最终输出到txt文档中. 如果是没有防盗链设置的站点,也可以使用脚本中的下载函数尝试直接下载. 本脚本是为了短期特定目标设计的,如果使用它爬其它特征的资源链接需自行修改配置 ...
- .NET Reactor使用教程(加密源代码示例)
更多:https://www.cnblogs.com/PiaoMiaoGongZi/category/1120300.html 1.打开 Eziriz .NET Reactor,主界面如图1所示: 图 ...
- 2、Jmeter测试
一.测试流程 1.添加本次测试计划 (右键-->添加-->Threads(Users)-->线程组) 2.设置线程数 (所谓线程数就是并发用户数) 3.在线程组内添加请求(右键--& ...
- Linux架构之Rsync守护进程推和拉
第三十三章 Rsync服务 33.1)Rsync基本概述 rsync是一款开源.快速.多功能.可实现全量及增量的本地或远程数据同步备份的优秀工具.rsync软件适用于Unix/linux/Window ...
- C++11的新特性:右值引用
先看代码 #include "pch.h" #include <iostream> #include <string> using namespace st ...
- Java 逻辑运算符相关解析
问:定简单说说 Java 中 & 与 && 有什么区别?| 与 || 呢? 答:& 是位运算符,&& 是布尔逻辑运算符,| 与 || 类似同理.在进行逻 ...
- 信号量计算问题--n个进程, 共享3个资源, 当前信号量为-1, 其他进程继续执行P操作, 那么信号量应该继续减
选B
- js中关键字 const , let , var 的用法区别
1.const定义的变量不可以修改,而且必须初始化. 2.var定义的变量可以修改,如果不初始化会输出undefined,不会报错. 3.let是块级作用域,函数内部使用let定义后,对函数外部无影响 ...
- vuex的mapState方法来获取vuex的state对象中属性
有两种写法 1.首先在组件中引入vuex的mapState方法: 首先在组件中引入vuex的mapState方法: import { mapState } from 'vuex' 然后在compute ...
- Flask路由之重定向
Flask框架提供了请求重定向功能,只需要使用 redirect_to即可, 示例代码如下: from flask import Flask, render_template, request, re ...