每日一题(22)——区间重合检测(二)(线段树)

本文详细介绍了线段树数据结构,包括构造、区间查询和区间修改操作,以及线段树在区间覆盖问题中的应用。通过实例展示了如何使用线段树解决区间查询和修改的问题,并给出了线段树在不同场景下的应用,如区间覆盖次数计算等。
摘要由CSDN通过智能技术生成

一、问题:给定一个窗口区域和系统界面上的N个窗口,判断这个窗口区域是否被已有的窗口覆盖。

 

二、数据结构之线段树

作者:Dong |可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
网址:

1、概述

线段树,也叫区间树,是一个完全二叉树,它在各个节点保存一条线段(即“子数组”),因而常用于解决数列维护问题,它基本能保证每个操作的复杂度为O(lgN)。

2、线段树基本操作

线段树的基本操作主要包括构造线段树,区间查询和区间修改。

(1) 线段树构造

首先介绍构造线段树的方法:让根节点表示区间[0,N-1],即所有N个数所组成的一个区间,然后,把区间分成两半,分别由左右子树表示。不难证明,这样的线段树的节点数只有2N-1个,是O(N)级别的,如图:

显然,构造线段树是一个递归的过程,伪代码如下:

//构造求解区间最小值的线段树
function 构造以v为根的子树
ifv所表示的区间内只有一个元素
v区间的最小值就是这个元素, 构造过程结束
endif
把v所属的区间一分为二,用w和x两个节点表示。
标记v的左儿子是w,右儿子是x
分别构造以w和以x为根的子树(递归)
v区间的最小值 <- min(w区间的最小值,x区间的最小值)
end function

线段树除了最后一层外,前面每一层的结点都是满的,因此线段树的深度

h =ceil(log(2n -1))=O(log n)。

(2) 区间查询

区间查询指用户输入一个区间,获取该区间的有关信息,如区间中最大值,最小值,第N大的值等。

比如前面一个图中所示的树,如果询问区间是[0,2],或者询问的区间是[3,3],不难直接找到对应的节点回答这一问题。但并不是所有的提问都这么容易回答,比如[0,3],就没有哪一个节点记录了这个区间的最小值。当然,解决方法也不难找到:把[0,2]和[3,3]两个区间(它们在整数意义上是相连的两个区间)的最小值“合并”起来,也就是求这两个最小值的最小值,就能求出[0,3]范围的最小值。同理,对于其他询问的区间,也都可以找到若干个相连的区间,合并后可以得到询问的区间。

区间查询的伪代码如下:

// node 为线段树的结点类型,其中Left 和Right 分别表示区间左右端点
// Lch 和Rch 分别表示指向左右孩子的指针
void Query(node *p, int a, int b) // 当前考察结点为p,查询区间为(a,b]
{
if(a <= 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值