Segment Tree 线段树算法(java)

线段树算法

  • Segment Tree 线段树算法
    • 代码演示
  • 蓄水池算法

Segment Tree 线段树算法

什么是线段树算法:
线段树(Segment Tree)是一种基于树结构的数据结构,用于解决区间查询问题,例如区间最大值、最小值、区间和等。线段树是一种高度平衡的二叉树,每个节点都代表了一个区间。下面我们来详细了解一下线段树算法。

线段树的构建
线段树的构建过程可以通过递归的方式实现。对于一个给定的数组,我们首先构建一个高度为 log n 的线段树,其中 n 是数组的长度。每个节点都代表了一个区间,例如左儿子节点代表[l, r],右儿子节点代表[r+1, r2]。具体的构建过程如下:
1.初始化根节点,区间为[0, n-1]。
2.对于每个节点,如果它的左右儿子节点存在,就递归构建左右儿子节点。
3.每个节点的值根据需要更新,例如查询最大值时,每个节点存储的值应该是该区间内的最大值
4.当构建到叶子节点时,将叶子节点的值存储为对应区间的值。

线段树查询
线段树查询可以通过递归的方式实现。对于一个查询区间[l, r],我们从根节点开始,根据区间与节点所代表区间的关系,逐步向下遍历子树,直到到达叶子节点。在遍历过程中,我们可以根据需要更新节点的值,例如查询最大值时,如果当前节点的值比查询区间的值更大,就将当前节点的值更新为查询区间的值。具体的查询过程如下:
1.从根节点开始,如果当前节点所代表的区间与查询区间有交集,就继续向下遍历。
2.如果当前节点的左儿子节点存在,并且左儿子节点所代表的区间与查询区间有交集,就递归查询左儿子节点。
3.如果当前节点的右

示例1:
在这里插入图片描述 线段树是一种二叉搜索树。他将一段区间划分为若干个单位区间,每个节点之间存储一个区间。思想类似于分治思想。

如图所示,线段树中每一个节点都存储着区间[1,10]中的信息,叶子节点的L = R。大致思想为:将大区间平分为2个小区间,每一个小区间再平分为更小的2个区间,以此类推直到每个区间的L = R,通过对这些区间的修改和查询来实现对大区间的修改和查询。
单点查找、修改的时间复杂度:O(log2n)
线段树维护的问题必须满足区间加法 例如:[1,3] + [2,4] = [1,4]。

代码演示

 public static class SegmentTree{//记录原数组的长度, 线段树下标是从1 开始,原数组是从0开始,private int MAXN;//保存原数组的信息,不过下标从1开始了private int[]arr;//模拟线段树维护记录区间和private int[]sum;//为累加和懒加载private int[]lazy;//区间更新的值private int[]change;//是否更新的标记private boolean[]update;public SegmentTree(int[] origin) {MAXN = origin.length + 1;for (int i = 1; i < MAXN;i++){arr[i] = origin[i - 1];}//用来记录逻辑概念中,某一范围的累加和信息。sum = new int[MAXN << 2];//用来支持逻辑概念中,某一个范围沒有往下透传的累加任务lazy = new int[MAXN << 2];//用来支持逻辑概念中,某一个范围更新任务,更新成了什么change = new int[MAXN << 2];// 用来支持逻辑概念中,某一个范围有没有更新操作的任务update = new boolean[MAXN << 2];}/*** rt 代表逻辑概念中 所在的位置* @param rt*/public void pushUp(int rt){sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}/*** 初始化线段树* 初始化时 先把sum数组填好* @param l* @param r* @param rt*/public void build(int l,int r,int rt){if (l == r){sum[rt] = arr[l];return;}int mid = (r + l) >> 1;build(l,mid,rt << 1);build(mid + 1,r,rt << 1 | 1);pushUp(rt);}/*** 任务往下分配* @param rt 当前位置* @param ln 分配任务的左边界* @param rn 分配任务的右边界*/private void pushDown(int rt,int ln,int rn){if (update[rt]){update[rt << 1] = true;update[rt << 1 | 1] = true;change[rt << 1] = change[rt];change[rt << 1 | 1] = change[rt];lazy[rt << 1] = 0;lazy[rt << 1 | 1] = 0;sum[rt << 1] = change[rt] * ln;sum[rt << 1 | 1] = change[rt] * rn;update[rt] = false;}//懒加载的数据分发下去if (lazy[rt] != 0){lazy[rt << 1] += lazy[rt];sum[rt << 1] += lazy[rt] * ln;lazy[rt << 1 | 1] += lazy[rt];sum[rt << 1 | 1] += lazy[rt] * rn;lazy[rt] = 0;}}/*** L - R 任务的范围,C 修改的大小* l r ,rt 所负责的范围。* @param L* @param R* @param C* @param l* @param r* @param rt*/public void add(int L,int R,int C,int l,int r,int rt){if (L <= l && r <= R){sum[rt] += C * (r - l + 1);lazy[rt] += C;return;}int mid = (r + l) >> 1;//任务没有全包,就下发。pushDown(rt,mid - l + 1,r - mid);if (L <= mid){add(L,R,C,l,mid,rt << 1);}if (R > mid){add(L,R,C,mid + 1,r,rt << 1 | 1);}pushUp(rt);}/***  //L - R 范围内所有值都变成 C*  //l - r 是 rt 所在位置的包含数字的范围* @param L* @param R* @param C* @param l* @param r* @param rt*/public void update(int L,int R,int C,int l,int r,int rt){//所在范围被全包了。if (L <= l && r <= R){change[rt] = C;update[rt] = true;sum[rt] = (r - l + 1) * C;lazy[rt] = 0;return ;}int mid = (r + l) >> 1;pushDown(rt,mid - l + 1,r - mid);if (L <= mid){update(L,R,C,l,mid ,rt << 1);}if (R > mid){update(L,R,C,mid + 1,r,rt << 1 | 1);}pushUp(rt);}/*** 查询*  //L - R 要查询的范围*   //l - r 是 rt 所包含的范围。* @param L* @param R* @param l* @param r* @param rt* @return*/public long query(int L,int R,int l,int r,int rt){if (L <= l && r <= R){return sum[rt];}int mid = (r + l) >> 1;pushDown(rt,mid - l + 1,r - mid);long ans = 0;if (L <= mid){ans += query(L,R,l,mid,rt << 1);}if (R > mid){ans += query(L,R,mid + 1, r, rt << 1 | 1);}return ans;}}

蓄水池算法

蓄水池算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/3438.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在阿里云linux上安装MySql数据库

我们先远程连接服务器 然后输入 sudo yum update重新运行一下 然后 sudo yum install mysql-server安装 mysql 服务 其中有两次 y n 选择 都选y就好了 然后 运行 sudo service mysqld start启动MySql 然后 我们查看一下MySql sudo service mysqld status

git rebase 合并提交

一. 合并提交步骤 git log --oneline 查看当前提交记录 git rebase -i HEAD~2 选择最后提交的2条记录进行合并进入编辑界面,将c865404的pick改为f, 表示向前合并也就是向cc5a54合并 编辑完之后:wq 保存并退出git rebase --continuegit push --force origin feature/v1.2 推送…

opencv -11 图像运算之按位逻辑运算(图像融合图像修复和去除)

按位逻辑运算是一种对图像进行像素级别的逻辑操作的方法&#xff0c;使用OpenCV的按位逻辑运算函数可以对图像进行位与&#xff08;AND&#xff09;、位或&#xff08;OR&#xff09;、位非&#xff08;NOT&#xff09;和位异或&#xff08;XOR&#xff09;等操作。 通俗点就是…

docker-compose搭建prometheus+grafana+钉钉告警

前言&#xff1a; 本文将介绍使用docker-compose部署搭建promtheus监控容器、主机、服务等相关状态&#xff1b; 配合granfana面板构建监控大屏&#xff1b; 由于grafana的报警不是很友好&#xff0c;使用dingtalk&#xff0c;配合altermanager&#xff0c;实现钉钉报警。 …

认识Spring(1)

hi,大家好,今天继续为大家带来Spring的相关内容 文章目录 &#x1f9c1;1.理解Spring和IOC&#x1f9c1;2.DI和DF&#x1f378;2.1什么是DI&#x1f378;2.2什么是DF&#x1f378;2.3DI和DF的区别 &#x1f9c1;3 Spring创建和使用&#x1f378;3.1创建Spring项目&#x1f361…

【机器人模拟-02】 模拟移动机器人设置里程计

一、说明 在本教程中,我将向您展示如何设置移动机器人的测程。本教程是“机器人模拟”指南中的第二个教程。测量位移是仿真中的重要内容,设置测程的官方教程在此页面上,但我将逐步引导您完成整个过程。 您可以在此处获取此项目的完整代码。让我们开始吧! 二、ROS 2 中的里程…

密码学学习笔记(十五):ECDSA - 椭圆曲线数字签名算法

椭圆曲线数字签名算法是DSA的一种椭圆曲线变体&#xff0c;它发明的初衷只是避免使用Schnorr签名的专利。椭圆曲线数字签名算法依赖于验证器中的私钥和主机用于验证验证器的公钥。它的缺点和DSA一样&#xff0c;它也没有提供安全性证明。 椭圆曲线算法 DSS&#xff08;数字签…

torch分布式通信基础

torch分布式通信基础 1. 点到点通信2. 集群通信 官网文档&#xff1a;WRITING DISTRIBUTED APPLICATIONS WITH PYTORCH 1. 点到点通信 # 同步&#xff0c;peer-2-peer数据传递 import os import torch import torch.distributed as dist import torch.multiprocessing as mpdef…

php 开发微信 h5 支付 APIv3 接入超详细流程

✨ 目录 &#x1f388; 申请商户号&#x1f388; 申请商户证书&#x1f388; 设置V3密钥&#x1f388; 开通H5支付&#x1f388; 设置支付域名&#x1f388; SDK 下载&#x1f388; 第一次下载平台证书&#x1f388;非第一次下载平台证书&#x1f388; H5下单 &#x1f388; 申…

【前端知识】React 基础巩固(二十八)——StrictMode

React 基础巩固(二十八)——StrictMode StrictMode StrictMode 是一个用来突出显示应用程序中潜在问题的工具 与 Fragment 一样&#xff0c;StrictMode 不会渲染任何可见的 UI为后代出发额外的检测和警告严格模式检查仅在开发模式下运行&#xff0c;不影响生产构建 严格模式检…

【DBA课程-笔记】第 3 章:MongoDB数据库核心知识

内容 一、MongoDB 数据库架构 A. MongoDB数据库体系架构 1. 存储引擎&#xff08;MongoDB Storage Engines&#xff09;&#xff1a; 2. MongoDB 数据逻辑架构 二、MongoDB 存储引擎 A. 查看mongodb服务器的状态 B. 查看引擎信息&#xff08;4.2.1 没有这个命令&#xf…

搭载下一代人工智能技术,微软推出Power Automate流程挖掘产品

在近日的Microsoft Inspire大会中&#xff0c;微软揭晓了他们即将推出的Power Automate流程挖掘产品&#xff0c;并计划在8月1日正式对外开放。 试用地址&#xff1a;https://powerautomate.microsoft.com/zh-cn/#home-signup 这款产品搭载了下一代人工智能技术&#xff0c;有…

基于 Fedora 38 的预期版本 Nobara 38 发布

导读基于 Fedora 38 的预期版本 Nobara 38 终于发布了&#xff0c;它带来了一系列用户友好的修复和功能增强。Nobara 是 Fedora Linux 的修改版本&#xff0c;旨在解决用户面临的常见问题&#xff0c;并提供开箱即用的顺滑的游戏、流媒体和内容创建体验。凭借一系列附加软件包和…

深度学习ai学习方向如何规划,算法竞赛,机器学习,搭建环境等答疑

目录 1了解人工智能的背景知识 2 补充数学或编程知识 3 熟悉机器学习工具库 4 系统的学习人工智能 5 动手去做一些AI应用 1了解人工智能的背景知识 一些虽然存在但是在研究或者工业上不常用的知识&#xff0c;为自己腾出更多的时间来去学习&#xff0c;研究。 人工智能里…

天翎MyApps低代码平台唯品会金牌客服管理系统

项目痛点&#xff1a; 作为一家知名的创新大型电商&#xff0c;唯品会秉承“传承品质生活&#xff0c;提升幸福体验”的企业使命。基于客服铁军锻造项目&#xff0c;实现基于金牌案例的提交、评审、积分&#xff0c;学习功能。 项目中的晋升机制、案例产生学习机制、双激励机制…

linux 基于debian_ubuntu AB系统适配(三)- overlayroot

Overlayroot Overlayroot是一个实用工具,允许您创建一个只读的根文件系统和一个可写的覆盖文件系统。这对于创建一个更安全和稳定的系统很有用,因为对系统所做的任何更改都将存储在覆盖文件系统中,可以很容易地丢弃或重置。 在Debian下,分离的系统在/userdata/rootfs_ove…

手把手教你搭建SpringCloud项目(九)集成OpenFeign服务接口调用

什么是微服务&#xff1f;一看就会系列&#xff01; 一、手把手教你搭建SpringCloud项目&#xff08;一&#xff09;图文详解&#xff0c;傻瓜式操作 二、手把手教你搭建SpringCloud项目&#xff08;二&#xff09;生产者与消费者 三、手把手教你搭建SpringCloud项目&#x…

【iOS】ARC实现

ARC由以下工具来实现&#xff1a; clang&#xff08;LLVM编译器&#xff09;3.0以上objc4 Objective-C运行时库493.9以上 下面我们&#xff0c;我们将围绕clang汇编输出和objc4库的源代码探究ARC实现 1. __strong修饰符 1.1 赋值给附有__strong修饰符的变量 看下面代码 {…

注释气泡图函数(更新)

之前我们写过一个原创可视化函数Dotplot_anno.R&#xff0c;nature级别图表&#xff1a;一个注释气泡热图函数&#xff08;适用于单细胞及普通数据&#xff09;。主要解决的问题是1) 单细胞基因可视化分组注释。2) Bulk RNA差异基因热图、气泡图。3) 富集分析结果气泡图展示。这…

【分布式训练】基于Pytorch的分布式数据并行训练

基于Pytorch的分布式数据并行训练 动机为什么要并行分布数据&#xff1f;现有资料的不足 Outline整体框架图带解释的最小demo示例没有multiprocessing开启multiprocessing 分布式训练启动方式混合精度训练&#xff08;采用apex&#xff09; 参考资料 简介&#xff1a; 在PyTorc…