线段树(基础)Segment Tree

本文介绍了线段树的基本概念,包括如何建立线段树、修改区间和进行区间查询。通过一个影子宽度的实例,详细阐述了线段树在区间问题中的应用,包括题目描述、解题思路和代码实现。最后进行了总结,并推荐了一个关于整数问题的实战题目。
摘要由CSDN通过智能技术生成

目录

一.What is Segment Tree?

1.概念

2.实践

(1)建树

(2)修改区间

(3)区间查询

二.How can we use it?

例:影子的宽度

(1)题目

(2)思路

(3)思维图

(4)代码

三.sum up(总结)

四.附:关于整数的简单题


一.What is Segment Tree?

1.概念

线段树是一种二叉搜索树,主要用于区间查询与修改,是树状数组的一种升级版。它的时间复杂度是:①建树O(nlog_{n});②查询O(log_{n})。先来说一说如何实践线段树。

2.实践

(1)建树

线段树中的每一个结点表示了一个区间[a,b];根节点表示的是“整体”的区间,每一个叶子节点表示了一个单位区间。

对于每一个非叶结点所表示的区间[a,b]:左儿子表示的区间为[a,(a+b)/2];右儿子表示的区间为[(a+b)/2+1,b]。

以下是一棵样例线段树:

附代码:

inline void build (int i, int l, int r){//i表示编号,l和r是左右区间端点
    tree[i].l = l, tree[i].r = r;
    int mid = (l + r) / 2;
    if (l == r)
        return ;
    build (i * 2, l, mid);
    build (i * 2 + 1, mid + 1, r);
}

(2)修改区间

对于修改区间,我无法给出准确的代码,但是总体思想是有的。就是找到被将被修改区间完全覆盖的区间,修改它并递归回到此区间所代表的节点的父节点。就拿上面的那个图来看,如果我要修改区间[3, 5],那么区间[3, 3]和[4, 5]将被修改。附一个样例代码(不通用),表示把区间[l, r]每一段的值修改成1:

void insert (int i, int l, int r){
    if (tree[i].r < l || tree[i].l > r)//如果此区间与修改区间完全不相干,直接返回
        return ;
    if (tree[i].l >= l && tree[i].r <= r){//此区间被将修改区间完全覆盖
        tree[i].cnt = (tree[i].r - tree[i].l + 1) * 1;//因为是每一段,所以整个区间的总值就是看这个区间的段数有多少段
      
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值