CF600E Lomsat gelral 权值线段树题解
时间:2021-07-16
本文章向大家介绍CF600E Lomsat gelral 权值线段树题解,主要包括CF600E Lomsat gelral 权值线段树题解使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前言
其实就是一道线段树合并的板子,因为机房要求写就写了。
题意
问 \(1\sim n\) 的子树中各个子树的众数和。
分析
其实,一般如果要求各个子树的某个东西,我们一般都是考虑 线段树合并/dsu on tree/dfn+其他数据结构(可能还有其他做法,只不过我太菜了不会),所以我才会说显然。
考虑将每个点都建一棵权值线段树,跑一次 \(dfs\), 将子树 合并,然后线段树中维护我们想要的东西,在这道题中就是数字出现的 最大次数 和 众数和。
关于时间复杂度:对于每次底层的合并,都会使两个数绑成一块,那最多进行 \(n\) 次,每次跑到底层需要 \(log_2(n)\),则时间复杂度:\(\mathcal {O}(nlog_2(n))\)。
关于左右区间合并,若出现的次数相等,贡献为两边相加,否则为次数大的那个。
Code
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#define LL long long
using namespace std;
const int MAXN = 1e5 + 5;
struct Segment_Tree {
int L, R, Max;
LL Sum;
}tree[MAXN * 65];
int n, a[MAXN], tot, root[MAXN];
LL ans[MAXN];
vector <int> v[MAXN];
int max_(int x, int y) { return x > y ? x : y; }
int add(int p, int x, int l, int r) {
if(!p) p = ++ tot;
if(l == r) { tree[p].Max = 1; tree[p].Sum = x; return p; }
int mid = (l + r) >> 1;
if(x <= mid) tree[p].L = add(tree[p].L, x, l, mid);
else tree[p].R = add(tree[p].R, x, mid + 1, r);
if(tree[tree[p].L].Max == tree[tree[p].R].Max) tree[p].Sum = tree[tree[p].L].Sum + tree[tree[p].R].Sum, tree[p].Max = max_(tree[tree[p].L].Max, tree[tree[p].R].Max);
else tree[p].Max = max_(tree[tree[p].L].Max, tree[tree[p].R].Max), tree[p].Sum = tree[tree[p].L].Max >= tree[tree[p].R].Max ? tree[tree[p].L].Sum : tree[tree[p].R].Sum;
return p;
}
int Merge(int p, int q, int l, int r) {
if(!p) return q;
if(!q) return p;
if(l == r) {
tree[p].Max += tree[q].Max; tree[p].Sum = tree[q].Sum;
return p;
}
int mid = (l + r) >> 1;
tree[p].L = Merge(tree[p].L, tree[q].L, l, mid);
tree[p].R = Merge(tree[p].R, tree[q].R, mid + 1, r);
if(tree[tree[p].L].Max == tree[tree[p].R].Max) tree[p].Sum = tree[tree[p].L].Sum + tree[tree[p].R].Sum, tree[p].Max = max_(tree[tree[p].L].Max, tree[tree[p].R].Max);
else tree[p].Max = max_(tree[tree[p].L].Max, tree[tree[p].R].Max), tree[p].Sum = tree[tree[p].L].Max >= tree[tree[p].R].Max ? tree[tree[p].L].Sum : tree[tree[p].R].Sum;
// printf("%d %d %d %lld\n", l, r, tree[p].Max, tree[p].Sum);
return p;
}
void dfs(int x, int fa) {
for(unsigned int i = 0; i < v[x].size(); i ++) {
int y = v[x][i]; if(y == fa) continue;
dfs(y, x); root[x] = Merge(root[x], root[y], 1, n);
}
ans[x] = tree[root[x]].Sum;
}
int main() {
int x, y;
scanf("%d", &n); tot = n;
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), root[i] = i, root[i] = add(root[i], a[i], 1, n);
for(int i = 1; i < n; i ++) {
scanf("%d%d", &x, &y); v[x].push_back(y); v[y].push_back(x);
}
dfs(1, -1);
for(int i = 1; i <= n; i ++) printf("%lld ", ans[i]);
return 0;
}
原文地址:https://www.cnblogs.com/Kidulthood/p/15019519.html
- 面试机器学习、大数据岗位时遇到的各种问题
- ThinkPHP连续签到小案例
- Windows环境配置Apache+Mysql+PHP
- 如何使用Retrofit获取服务器返回来的JSON字符串
- Python相对、绝对导入浅析
- spring profile 多环境配置管理
- 论linux下计划任务
- 20条Linux命令面试问答
- CentOS 6 使用 yum 安装MongoDB及服务器端配置
- java处理高并发高负载类网站的优化方法
- 每一个程序员需要了解的10个Linux命令
- php_curl.dll libssh2.dll 始终无法加载的原因 及解决办法
- ant安装、环境变量配置及验证
- MySQL性能优化的最佳20+条经验
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel框架中间件 except 和 only 的用法示例
- 浅析Python 多行匹配模式
- PHP命名空间定义与用法实例分析
- php array_chunk()函数用法与注意事项
- Laravel如何同时连接多个数据库详解
- PHP面向对象程序设计中的self、static、parent关键字用法分析
- php实现简单的守护进程创建、开启与关闭操作
- 关于CentOs系统自带python和yum卸载后的解决办法
- php5对象复制、clone、浅复制与深复制实例详解
- Linux命令行快速技巧之定位一个文件的办法
- ubuntu中python调用C/C++办法之动态链接库详解
- linux中使用boost.python调用c++动态库的办法
- 在Linux系统下上传项目到码云的办法
- PHP global全局变量经典应用与注意事项分析【附$GLOBALS用法对比】 原创
- Linux(Ubuntu 18.04)上安装Anaconda步骤详解