线段树的代码模板

【Autoware】Autoware.universe安装过程与问题记录 Autoware.universe安装过程与问题记录 阅读详情

线段树的应用:

1)求面积:

一.坐标离散化;

二.垂直边按x坐标排序;

三.从左往右用线段树处理垂直边,累计每个离散x区间长度和线段树长度的乘积。

2)求周长:

一.坐标离散化;

二.垂直边按x坐标排序,第二关键字为入边优于出边;

三.从左往右用线段树处理垂直边,在每个离散点上先加入所有入边,累计线段树长度变化值,再删除所有出边,累计线段树长度变化值;

四.水平边按y坐标排序,第二关键字为入边优于出边;

五.从上往下用线段树处理水平边,在每个离散点上先加入所有入边,累计线段树长度变化值,再删除所有出边,累计线段树长度变化值。

 

基本线段树代码:

//基本线段树,可以处理加入边和删除边不同的情况

//t是传入的线段树的根节点

//l0, r0是传入的线段树的节点范围

//l,r是线段树中的一个区间的两个端点

#define MAXN 10000

 

struct segtree

{

       int n;

       int cnt[MAXN];   //覆盖这一节点区间的线段的个数

int len[MAXN];   //区间的长度

       segtree(int t) : n(t)

       {

              for(int i=1; i<=t; i++)     //初始化数组

                     cnt[i] = len[i] = 0;

       };

 

       //成员函数啦

       void update(int t, int l, int r); //更新以t为根节点的线段树的区间长度len[t]

       void inc_seg(int t, int l0, int r0, int l, int r);  //加入边

       void dec_seg(int t, int l0, int r0, int l, int r); //删除边

       int seg_len(int t, int l0, int r0, int l, int r);     //求线段树的长度

};

 

//区间(l, r)的长度

int length(int l, int r)

{

       return (r - l);

}

 

//更新以t为根节点的线段树的区间长度len[t]

void segtree::update(int t, int l, int r)

{

       if(cnt[t] || (r-l)==1)

              len[t] = length(l, r);

       else

              len[t] = len[t+t] + len[t+t+1];        //左右子树区间长度之和

}

 

//向以t为根节点、区间为(l0, r0)的线段树中加入区间(l, r)

void segtree::inc_seg(int t, int l0, int r0, int l, int r)

{

       if(l0 == l && r0 == r)

       {

              cnt[t]++;

       }

       else

       {

              int m0 = (l0 + r0)>>1;          //即(l0+r0)/2

              if(l < m0)     //覆盖到左孩子区间

              {

                     //向左孩子区间插入(l, r)

                     inc_seg(t+t, l0, m0, l, m0<r?m0:r);

              }

              if(r>m0)      //覆盖到右孩子区间

              {

                     //向右孩子区间插入(l, r)

                     inc_seg(t+t+1, m0, r0, m0>l?m0:l, r);

              }

              if(cnt[t+t] && cnt[t+t+1])

              {

                     cnt[t+t]--;

                     update(t+t, l0, m0);

                     cnt[t+t+1]--;

                     update(t+t+1, m0, r0);

                     cnt[t]++;

              }

       }

       update(t, l0, r0);

}

 

//向以t为根节点、区间为(l0, r0)的线段树中删除区间(l, r)

void segtree::dec_seg(int t, int l0, int r0, int l, int r)

{

       if(l0 == l && r0 == r)

              cnt[t]--;

       else if(cnt[t])

       {

              cnt[t]--;

              if(l>l0)

                     inc_seg(t, l0, r0, l0, l);       //抵消上面的cnt[t]--

              if(r<r0)

                     inc_seg(t, l0, r0, r, r0);      //同上

       }

       else

       {

              int m0 = (l0 + r0)>>1;

              if(l<m0)

                     dec_seg(t+t, l0, m0, l, m0<r?m0:r);

              if(r>m0)

                     dec_seg(t+t+1, m0, r0, m0>l?m0:l, r);

       }

       update(t, l0, r0);

}

 

//求线段树中区间(l, r)的区间长度,(l0, r0)是线段树的初始节点区间

int segtree::seg_len(int t, int l0, int r0, int l, int r)

{

       if(cnt[t] || (l0==l && r0==r))

              return len[t];

       else

       {

              int m0 = (l0+r0)>>1;

              int ret = 0;

              if(l<m0)

                     ret += seg_len(t+t, l0, m0, l, m0<r?m0:r);

              if(r>m0)

                     ret += seg_len(t+t+1, m0, r0, l, m0>l?m0:l, r);

 

              return ret;

       }

}

 

线段树的扩展代码如下:

//线段树扩展,可以计算长度和线段树

//可以处理加入边和删除边不同的情况

//t是传入的线段树的根节点

//l0, r0是传入的线段树的节点范围

//l,r是线段树中的一个区间的两个端点

#define MAXN 10000

 

struct segtree

{

       int n;

       int cnt[MAXN]; //覆盖这一节点区间的线段的个数

int len[MAXN];   //区间的长度

       int cut[MAXN];   //存放线段数

       int bl[MAXN];     //标识左端点是否被区间覆盖到

       int br[MAXN];    //标识右端点是否被区间覆盖到

       segtree(int t) : n(t)

       {

              for(int i=1; i<=t; i++)     //初始化数组

                     cnt[i] = len[i] = cut[i] = bl[i] = br[i] = 0;

       };

 

       //函数啦

       void update(int t, int l, int r);  //更新以t为根节点的线段树的区间长度len[t]

       void inc_seg(int t, int l0, int r0, int l, int r);  //加入边

       void dec_seg(int t, int l0, int r0, int l, int r); //删除边

       int seg_len(int t, int l0, int r0, int l, int r);     //求区间的长度

       int seg_cut(int t, int l0, int r0, int l, int r);     //求线段数

};

 

 

int length(int l, int r)

{

       return (r - l);

}

//更新以t为根节点、区间为[l, r]的线段树的区间长度len[t]

//和线段数cut[t]及其左右端点标识bl[t]和br[t]

void segtree::update(int t, int l, int r)

{

       if(cnt[t] || (r-l)==1)

       {

              len[t] = length(l, r);

              cut[t] = bl[t] = br[t] = 1;

       }

       else

       {

              len[t] = len[t+t] + len[t+t+1];        //左右子树长度之和

              cut[t] = cut[t+t] + cut[t+t+1];

              if(br[t+t] && bl[t+t+1])

                     cut[t]--;

              bl[t] = bl[t+t];

              br[t] = br[t+t+1];

       }

}

//向以t为根节点、区间为(l0, r0)的线段树中加入区间(l, r)

void segtree::inc_seg(int t, int l0, int r0, int l, int r)

{

       if(l0 == l && r0 == r)

       {

              cnt[t]++;

       }

       else

       {

              int m0 = (l0 + r0)>>1;          //即(l0+r0)/2

 

              if(l < m0)     //覆盖到左孩子区间

              {

                     //向左孩子区间插入(l, r)

                     inc_seg(t+t, l0, m0, l, m0<r?m0:r);

              }

 

              if(r>m0)      //覆盖到右孩子区间

              {

                     //向右孩子区间插入(l, r)

                     inc_seg(t+t+1, m0, r0, m0>l?m0:l, r);

              }

 

              if(cnt[t+t] && cnt[t+t+1])

              {

                     cnt[t+t]--;

                     update(t+t, l0, m0);

                     cnt[t+t+1]--;

                     update(t+t+1, m0, r0);

                     cnt[t]++;

              }

       }

       update(t, l0, r0);

}

//向以t为根节点、区间为(l0, r0)的线段树中删除区间(l, r)

void segtree::dec_seg(int t, int l0, int r0, int l, int r)

{

       if(l0 == l && r0 == r)

              cnt[t]--;

       else if(cnt[t])

       {

              cnt[t]--;

              if(l>l0)

                     inc_seg(t, l0, r0, l0, l);       //抵消上面的cnt[t]--

              if(r<r0)

                     inc_seg(t, l0, r0, r, r0);      //同上

       }

       else

       {

              int m0 = (l0 + r0)>>1;

              if(l<m0)

                     dec_seg(t+t, l0, m0, l, m0<r?m0:r);

              if(r>m0)

                     dec_seg(t+t+1, m0, r0, m0>l?m0:l, r);

       }

       update(t, l0, r0);

}

//求线段树中区间(l, r)的区间长度,(l0, r0)是线段树的初始节点区间

int segtree::seg_len(int t, int l0, int r0, int l, int r)

{

       if(cnt[t] || (l0==l && r0==r))

              return len[t];

       else

       {

              int m0 = (l0+r0)>>1;

              int ret = 0;

              if(l<m0)

                     ret += seg_len(t+t, l0, m0, l, m0<r?m0:r);

              if(r>m0)

                     ret += seg_len(t+t+1, m0, r0, l, m0>l?m0:l, r);

 

              return ret;

       }

}

 

//求线段树中区间(l, r)的连续线段数,(l0, r0)是线段树的初始节点区间

int segtree::seg_cut(int t, int l0, int r0, int l, int r)

{

       if(cnt[t])

              return 1;

       if(l0 == l && r0 == r)

              return cut[t];

       else

       {

              int m0 = (l0+r0)>>1;

              int ret = 0;

              if(l < m0)

              {

                     ret += seg_cut(t+t, l0, m0, l, m0<r?m0:r);

              }

              if(r > m0)

              {

                     ret += seg_cut(t+t+1, m0, r0, m0>l?m0:l, r);

              }

              if(l<m0 && r>m0 && br[t+t] && bl[t+t+1])

                     ret--;

              return ret;

       }

}

传导案例:某医疗仪器传导骚扰整改案例 紫外线光疗仪是一种专业的医疗设备,主要用于治疗银屑病、白癜风等皮肤疾病。该设备采用物理治疗技术,通过特定波长的紫外线照射人体来达到治疗效果。自1984年窄谱中波紫外线(NB-UVB)应用于临床以来,该技术已成为治疗早期蕈样肉芽肿(MF)的有效方法之一。作为二类医疗器械,紫外线光疗仪必须符合严格的电磁兼容性(EMC)标准,这不仅关系到设备自身的稳定运行,更关乎患者的使用安全和治疗效果。紫外线光疗仪传导骚扰整改案例充分展示了系统性EMC设计的重要性。 阅读详情

相关推荐

Linux之GTK系列教程

00、背上行囊1——程序员学习之道 01、背上行囊2——为什么要学习GTK 02、背上行囊3——GUI概述 03、背上行囊4——GTK简介 04、背上行囊5——GTK环境搭建( Linux ) 05、背上行囊6——GTK环境搭建( windows ) 06、踏上旅途1——一个简单的空白窗口 07、踏上旅途2——控件的添加 08、踏上旅途3——布局容器之水平布局 09、踏上旅途

每天积累一点点 2万+

线段树模板

线段树的适用范围很广,可以在线维护修改以及查询区间上的最值,求和。对于线段树来说,每次更新以及查询的时间复杂度为O(logn)。

qq_39530733的博客 1129

别再只用跳层连接了!手把手教你用DASI和MDCR模块提升红外小目标检测精度

本文详细介绍了如何利用DASI和MDCR模块提升红外小目标检测精度。通过分析传统跳层连接的缺陷,提出维度感知的特征选择性融合(DASI)和多尺度感受野精炼器(MDCR)的创新方案,显著提升小目标检测性能。实验证明,该方法在多个场景下AP@0.5提升达15.4%,特别适用于安防监控和遥感图像分析。

weixin_28715081的博客 224

线段树模板(个人)

【代码】线段树模板。

nzdd11的博客 194

AI量化投资开源平台——Qlib(微矿)的学习使用笔记(随缘更新)

Qlib 涵盖了量化投资的全过程,为用户的 AI 算法提供了高性能的底层基础架构,从框架设计上让用户可以更容易地应用 AI 算法来辅助解决量化投资的各个关键问题(例如 Alpha 预测,风险预测,市场动态性建模)。本文旨在记录一些面向初学者的基础内容。

in_void的博客 3133

继电保护原理1.2-反时限过流保护

反时限过流保护

让你爱上电路设计 1万+

线段树基本代码

#include <iostream> #include <algorithm> #include <cmath> #include <string> #include <vector> #include <map> using namespace std; #define maxn 100007//元素总个数 #define ls l,m,rt*2 #define rs m+1,r,rt*2+1 int Sum[maxn * 2]..

weixin_54010759的博客 907

专栏目录:Linux 内存管理子系统的进化——从 MM 到 HMM

专栏梳理了Linux内存管理子系统从经典MM到异构内存管理(HMM)的演进历程。内容分为六大部分:首先介绍经典MM基础,包括虚拟地址空间、页表、VMA等核心机制;其次分析MM通用框架如页表遍历、NUMA迁移等;然后探讨设备内存引入的关键技术,如ZONE_DEVICE和dev_pagemap;接着深入解析HMM核心机制及其与DMA的集成;随后通过多个实际驱动案例展示HMM应用;最后讨论大页支持等进阶主题。专栏采用"经典机制→问题→扩展方案"的三段式结构,帮助开发者理解Linux如何通过HMM实现设备内存管理。

图形/计算GPU的驱动与虚拟化技术分享园地 868

9.2 线段树详解+模板代码

线段树详解+模板代码

m0_62709362的博客 839

《多模态融合改进》支持目标检测、目标分割、OBB、姿态估计,配置教程

本文以为例,讲解如何配置,支持替换专栏里所有的改进方式。

Limiiiing的博客 795

【WRF模拟】保存wrf输出文件到指定目录+仅输出指定空间域/变量文件

修改wrf命令以更改指定输出文件目录等

WW、forever的博客 543

线段树模板代码(无注释)

含区间修改、点修改、区间查询、懒惰标记(lazytag)的区间求和,可通过。

weixin_66707711的博客 304

Transformers 实战修炼与源码剖析专栏大纲

本专栏以 Hugging Face Transformers 为主线,围绕“能用、会调、敢上线、懂源码”四个目标展开。内容不把理论堆成公式墙,而是用真实或拟真的业务场景驱动:客服分类、合同抽取、知识库问答、模型微调、推理服务、监控告警、源码扩展等。采用“业务痛点 → 三人剧本对话 → 代码实战 → 总结思考”的四段式结构,让读者在动手完成一个个小项目的过程中,逐步理解 Tokenizer、Model、Pipeline、Trainer、Generation、PEFT、Accelerate、Serving等概念

davidwang456的专栏 922

线段树模板代码

# include &lt;bits/stdc++.h&gt;///线段树模板代码 using namespace std; # define MAXN 50005 int data[MAXN]; int sum[MAXN*4]; int suy, L, R; void build(int root, int l, int r) { if(l==r) sum[root]=d...

qq_37495823的博客 213

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

线段树代码模板

区间查询/区间修改(加减)的模板代码 #include<bits/stdc++.h> using namespace std; const int N = 1e5+10; int a[N]; struct node { int l,r,sum,lz; int mx,mn; } T[N*4]; //建树 void build(int i, int l, int r) { T[i].l = l; T[i].r = r; T[i].lz = 0;

MC的博客 221

线段树&树状数组代码模板

参考:线段树介绍 静态线段树 假设大小为n,则至少需要申请大小为4*n的数组,对应力扣:通过指令创建有序数组,代码模板: class SegTree{ int n; int[] arr; SegTree(int n){ this.n = n; this.arr = new int[4*n]; } public void update(int x){ update(1,1,n,x); } public in

weixin_43111232的博客 358

【数据结构】线段树算法介绍及模板代码

【数据结构】线段树算法介绍及模板代码

un_fired的博客 553

洛谷 - 【模板】线段树 (区间修改与区间求和) 模板代码

模板题 板子代码 #include <bits/stdc++.h> inline long long read(){char c = getchar();long long x = 0,s = 1; while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();} while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();} retu

give it a try 272

一篇线段树 从入门到进阶 实现原理与代码模板

线段树是什么 线段树是啥,简单来说就是既方便我们求一个数组某区间的和,又方便我们修改数组的某个元素的一种数据结构。属于二叉搜索树。 对于一个普通数组来说,我们修改某一元素的时间复杂度是O(1),但求某区间和的时间复杂度是O(n)。 若使用前缀和,我们求某区间和的复杂度是O(1),但我们修改某一元素的复杂度是O(n)。 为了方便我们又修改又求和,我们就使用线段树来均衡这两个操作的复杂度,把他们都平均到O(logn)。 具体操作 我们通常用一个数组来模拟一棵满二叉树,该二叉树的根结点保存的是数组0-n所有元素的

harry12138小白的博客 449

代码源 线段树模板

思路:我们需要维护的东西是序列的最小值和最小值个数这道题没有修改操作,因此不考虑修改然后考虑Pushup最小值很简单,直接取min最小值个数怎么维护呢?考虑这个区间需要维护的值如何从左右两个区间获得如果左右两个子区间的最小值相同,那么就可以直接相加否则,如果这个区间的最小值是左区间最小值,直接赋值左区间的否则就是右区间的学一学dls的代码风格,感觉很高级QwQ。

weixin_62528401的博客 191

线段树简介及代码模板

树状数组可以在 O(logn) 的时间复杂度内实现单点修改、区间查询。 相对于树状数组,线段树更加通用,代码更长,功能也更加强大。 线段树是一种基于分治思想的二叉树结构,用于在区间上进行信息统计。 线段树可以在 O(logn) 的时间复杂度内实现单点修改、区间修改、区间查询(区间求和,求区间最大值,求区间最小值)等操作。 线段树的一些性质: 1、每个节点都代表一个区间 2、根节点代表的区间是整个统计范围,如 [1, N] 3、线段树的每个叶节点都代表长度为 1 的元区间 [x, x] 4、对于每个内部节点

默的博客 706

代码模板-线段树(单点修改,区间查询)

【代码】代码模板-线段树(单点修改,区间查询)

qq_75125305的博客 203

线段树模板,c++代码实现

参考博客: mhr 线段树:是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,实际应用时一般还要开4N的数组以免越界,因此有时需要离散化让空间压缩。 ......

qq_24471135的博客 2558

线段树模板代码+详细注释

#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define N 300005 int num[N];//数据数组,用于存放数据 int tree[N<<2];//线段树数组,用于构造线段树 int lazy[N<<2];//懒惰标...

A's World 288
上一篇: 《认清C++语言》之--内存管理
下一篇: Parliament--POJ--1032
ACE1985
博客等级 码龄17年 1307粉丝 308原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值