线段树详解——影子宽度

这篇具有很好参考价值的文章主要介绍了线段树详解——影子宽度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

OK,今天来讲一讲线段树~~

线段树是什么

线段树( S e g m e n t Segment Segment    T r e e ~~Tree   Tree)是一种二叉树,用于区间查询。线段树的每个节点表示一个区间,根节点表示整个区间,子节点表示区间的一半。线段树的典型应用是解决区间查询问题,例如区间最大值、区间最小值等。

线段树的实现

线段树的构建过程可以通过递归实现。给定一个数组 a r r arr arr,线段树的根节点表示 a r r [ 0 ] arr[0] arr[0] a r r [ n − 1 ] arr[n-1] arr[n1]之间的区间和(或其他区间操作)。根节点的左子节点表示 a r r [ 0 ] arr[0] arr[0] a r r [ ( n − 1 ) / 2 ] arr[(n-1)/2] arr[(n1)/2]之间的区间和,右子节点表示 a r r [ ( n − 1 ) / 2 + 1 ] arr[(n-1)/2+1] arr[(n1)/2+1] a r r [ n − 1 ] arr[n-1] arr[n1]之间的区间和。依次类推,直到区间被划分为长度为1的节点。

线段树的每个节点都会记录该节点表示的区间的一些统计信息,例如区间和、区间最大值、区间最小值等。该统计信息可以通过节点的左子节点和右子节点的统计信息来计算得到。

当要查询的区间与当前节点表示的区间有重叠时,查询操作会继续向下递归。当要查询的区间与当前节点表示的区间完全相等时,查询操作可以直接返回当前节点的统计信息。当要查询的区间在当前节点表示的区间的左半部分时,查询操作会向左子节点递归。当要查询的区间在当前节点表示的区间的右半部分时,查询操作会向右子节点递归。

当要更新的位置在当前节点表示的区间内时,更新操作会继续向下递归。当更新到叶子节点时,将该位置的值更新为给定的新值。然后,更新操作会向上递归,将更新后的值传递给父节点并重新计算父节点的统计信息。

线段树的时间复杂度

线段树的时间复杂度为 O ( l o g ( n ) ) O(log(n)) O(log(n)),其中n为数组的长度。这是因为构建线段树需要对每个节点进行一次操作,总共需要 O ( n ) O(n) O(n)的时间。查询操作的时间复杂度为 O ( l o g ( n ) ) O(log(n)) O(log(n)),因为查询的过程类似于二分查找,每次将查询范围缩小一半,最多需要递归 l o g ( n ) log(n) log(n)次。更新操作的时间复杂度也为 O ( l o g ( n ) ) O(log(n)) O(log(n))

线段树是一种非常强大的数据结构,可以用于解决各种区间查询问题。然而,线段树的应用并不局限于时间复杂度为 O ( l o g ( n ) ) O(log(n)) O(log(n))的问题,它还可以结合其他数据结构和算法来实现更高效的解决方案。例如,线段树可以与离散化、树状数组等结合使用,用于解决动态区间查询问题。同时,线段树还可以用于解决一些特殊情况下的区间查询问题,例如动态维护滑动窗口中的最大值、最小值等。

线段树的应用

线段树的应用非常广泛,以下是一些常见的应用场景:

  • 区间最小值/最大值查询:通过线段树可以在 O ( l o g ( n ) ) O(log(n)) O(log(n))的时间内找到任意区间的最小值或最大值。这在处理动态数据的情况下非常有用,例如动态维护滑动窗口的最小值、最大值。

  • 区间和查询:线段树可以用来快速计算区间内所有元素的和。这在求解数组范围内的连续子数组和、处理区间加法或区间更新操作等问题非常有用。

  • 区间更新:线段树可以将区间内的某个值更新为新值。这在处理动态修改数据的情况下非常有用,例如修改数组某个位置的值,或者将区间内的所有元素增加某个固定值。

  • 区间统计:除了求和、最小值、最大值等基本操作外,线段树还可以做更复杂的区间统计操作。例如,可以通过线段树求解区间内的第 k k k小元素,或者统计区间内有多少个不同的元素等。

  • 离散化:离散化是一种将连续的数据映射到离散的区间中的方法。通过使用线段树可以很方便地实现离散化操作,将大量的连续数据映射到有限的离散区间内,从而减小数据规模,提高查询效率。

  • 区间交集查询:线段树可以用于判断两个区间是否有交集,以及计算出两个区间的交集。这在处理区间重叠问题、查找共同区间等场景下非常有用。

  • 区间覆盖查询:线段树可以用于快速查找某个区间是否完全被覆盖,以及计算出所有覆盖某个区间的区间。这在处理区间合并、区间分割等问题非常有用。

线段树是一种非常强大而灵活的数据结构,可以根据需求进行扩展和优化。通过合理地设计数据结构和算法,线段树可以高效地解决各种区间查询问题,提高程序的性能和可扩展性。

线段树的节点结构

线段树的节点结构一般包含以下几个属性:

start 和 end:表示当前节点所代表的区间的起始和结束位置。
一个外挂:依题目而定

其他操作和优化

线段树还可以进行一些其他的操作和优化,例如:

  • 惰性更新:使用标记来延迟更新,减少更新操作的次数,提高效率。
  • 区间增量:维护区间值的增量,而不是直接修改区间的值,可以减少更新操作的次数。
  • 动态修改:支持在原始数据的基础上进行修改,而不需要重新构建整个线段树。

例题——影子宽度

精灵王的桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如下图所示。现在从桌子的前方射来一束平行光,把盒子的影子投射到了墙上。问影子的总宽度是多少?
线段树详解——影子宽度,C++专栏,java,算法,javascript

输入输出格式

输入格式

  • 第1行:盒子的个数N(1≤=N≤10000)。
  • 第2…N+1行:每个盒子的起始位置S和结束位置T(1≤S, T≤100000)。

输出格式

  • 第1行:包含一个整数,表示影子的总宽度。

输入输出样例

输入样例

4
1 2
3 5
4 6
5 6

输出样例

4

例题讲解

这题纯纯版题呀!!文章来源地址https://www.toymoban.com/news/detail-660535.html

#include <bits/stdc++.h>
using namespace std;
const int N=120000;
int n,m,maxx,minn,a[N],b[N],cover[4*N];
void insert(int idx,int ll,int rr,int x,int y) {
	if (x<=ll && y>=rr)		//如果区间范围包含当前线段
		cover[idx]=1;
	if(cover[idx]==1)	//如果当前线段已经被标记了
		return;
	int mid=(ll+rr)/2;
	if (y<=mid)
		insert(idx*2,ll,mid,x,y);	//左子树递归
	else if (x>=mid)
		insert(idx*2+1,mid,rr,x,y);		//右子树递归
	else {		//拆分成两边,分别递归
		insert(idx*2,ll,mid,x,y);
		insert(idx*2+1,mid,rr,x,y);
	}
}
int count(int idx,int ll,int rr,int x,int y) {
	if (cover[idx]==1)		//如果当前线段被标记
		return rr-ll;		//返回长度
	if (rr-ll>1) {		//如果当前线段还是一个线段
		int mid=(ll+rr)/2;
		int tx=count(idx*2,ll,mid,x,y);
		int ty=count(idx*2+1,mid,rr,x,y);
		return tx+ty;
	}
	return 0;
}
int main() {
	scanf ("%d",&n);
	for (int i=1;i<=n;i++) {
		scanf("%d%d",&a[i],&b[i]);
		if (a[i]>maxx)
			maxx=a[i];
		if (a[i]<minn)
			minn=a[i];
		if (b[i]>maxx)
			maxx=b[i];
		if (b[i]<minn)
			minn=b[i];
		//一堆判断,求最大边界和最小边界
		//有时候 是输入的数
	}
	for (int i=1;i<=n;i++)
		insert(1,minn,maxx,a[i],b[i]);		//标记线段
	printf("%d",count(1,minn,maxx,minn,maxx));		//输出结果
	return 0;
}

到了这里,关于线段树详解——影子宽度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法】树状数组和线段树

    O ( l o g n ) O(logn) O ( l o g n ) :单点修改、区间查询 与前缀和的区别: 前缀和是离线的,每次动态修改原数组某个元素,都需要重新求一遍前缀和,因此单点修改是 O ( n ) O(n) O ( n ) 的,区间查询则是 O ( 1 ) O(1) O ( 1 ) 树状数组是在线的,单点修改和区间查询都是 O ( l o g n ) O(

    2024年02月19日
    浏览(47)
  • 超详解线段树(浅显易懂,几乎涵盖所有线段树类型讲解,匠心之作,图文并茂)

    线段树是一种 二叉搜索树 ,而 二叉搜索树 ,首先 满足二叉树 ,即 每个结点 最多有 两颗子树 ,并且是一颗 搜索树 ,我们要知道,线段树的每个结点都存储了 一个区间 ,也可以理解成 一个线段 ,而 搜索 ,就是在这些 线段 上进行 搜索操作 得到你想要的 答案 。 线段树

    2024年02月05日
    浏览(46)
  • 算法41:掉落的方块(力扣699题)----线段树

    题目: https://leetcode.cn/problems/falling-squares/description/ 在二维平面上的 x 轴上,放置着一些方块。 给你一个二维整数数组  positions  ,其中  positions[i] = [lefti, sideLengthi]  表示:第  i  个方块边长为  sideLengthi  ,其左侧边与 x 轴上坐标点  lefti  对齐。 每个方块都从一个比目

    2024年02月22日
    浏览(43)
  • 【Java EE】-JavaScript详解

    作者 :学Java的冬瓜 博客主页 :☀冬瓜的主页🌙 专栏 :【JavaEE】 分享 : 且视他人如盏盏鬼火,大胆地去走你的道路。——史铁生《病隙碎笔》 主要内容 :HTML中引入JS的三种方式。JS语法分析,JS是动态弱类型语言,JS中的数组、方法、对象。JSWebAPI学习,选中元素和单击事

    2023年04月25日
    浏览(42)
  • 华为OD机试 - 最少数量线段覆盖| 机试题算法思路 【2023】

    华为OD机试 - 简易压缩算法(Python) | 机试题算法思路 【2023】 华为OD机试题 - 获取最大软件版本号(JavaScript) 华为OD机试 - 猜字谜(Python) | 机试题+算法思路 【2023】 华为OD机试 - 删除指定目录(Python) | 机试题算法思路 【2023】 华为OD机试 - 自动曝光(Python) | 机试题算法

    2023年04月25日
    浏览(43)
  • 【Java 进阶篇】JavaScript 正则表达式(RegExp)详解

    JavaScript 正则表达式,通常简写为 RegExp,是一种强大的文本匹配工具,它允许你通过一种灵活的语法来查找和替换字符串中的文本。正则表达式在编程中用途广泛,不仅限于 JavaScript,在许多编程语言中也都有类似的实现。 正则表达式,简称正则或RegExp,是一个用于描述字符

    2024年02月07日
    浏览(55)
  • Java线段树(含面试大厂题和源码)

    线段树(Segment Tree)是一种用于处理区间查询和更新问题的数据结构,特别是在需要对连续区间进行操作时非常有效。线段树可以快速地对区间求和、求最小值/最大值、判断某个值的存在性等问题进行响应。 线段树的特点: 高效性 :线段树能够在对数时间内完成区间查询和

    2024年04月12日
    浏览(40)
  • 宽度优先搜索算法(BFS)

    宽度优先搜索算法(BFS) (也称为 广度优先搜索 )主要运用于树、图和矩阵(这三种可以都归类在图中),用于在图中从起始顶点开始 逐层 地向外探索,直到找到目标顶点为止。 在本篇文章中,我们主要讨论其在 树 中的运用 树的宽度优先搜索 即 树的层序遍历 :逐层访

    2024年03月12日
    浏览(49)
  • 算法:BFS宽度优先遍历

    本篇总结的是BFS算法,BFS算法相比起DFS算法来说还是比较简单的 这里提供一种双端队列的做法,也可以在合适的层数逆序

    2024年02月21日
    浏览(57)
  • 【算法每日一练]-结构优化(保姆级教程 篇4 树状数组,线段树,分块模板篇)

    目录 分块 分块算法步骤: 树状数组 树状数组步骤: 线段树点更新 点更新步骤: 线段树区间更新 区间更新步骤: 不同于倍增和前缀和与差分序列。 前缀和处理不更新的区间和 差分处理离线的区间更新问题 倍增处理离线的区间最值问题 分块,树状数组,线段树: 分块处

    2024年02月04日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包