线段树学习笔记(单点更新+区间查询最大值+lazy标记+pushdown操作+区间更新+求区间和)

本文介绍了线段树的概念、性质及应用,包括如何创建线段树、单点更新、区间查询最大最小值、延迟标记(懒人标记)和pushdown操作、区间更新以及求区间和。线段树作为一种平衡二叉搜索树,常用于区间数据维护,如求区间和、最大值等,通过延迟标记实现区间更新的高效处理。
摘要由CSDN通过智能技术生成

目录


  • 什么是线段树?

  • 线段树基本操作:

  • 创建线段树

  • 线段树单点更新

  • 区间查询最大最小值

  • 延迟标记(懒人标记)+pushdown操作

  • 区间更新

  • 求区间和

注:以下所有代码都是针对维护区间和的。


  • 什么是线段树?

    线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。
    性质:对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b]。因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度。

  • 举个例子

这里写图片描述

  • 创建一个线段树

线段树成员:

struct node
{
    int val;  //具体数值
    int len;  //覆盖区间长度
    int lazy; //延迟标记
    int l,r;  //左右儿子编号
}tree[300005];

建树思想:递归建树,遇到叶子节点直接赋值,否则递归遍历左右建树,最后回溯即可。

void build(int root,int l,int r)  //建树 
{
    int mid;
    tree[root].l=l;tree[root].r=r;
    tree[root].len=r-l+1;
    if (l==r) tree[root].val=arr[l];
    else
    {
        mid=(l+r)/2;
        build(root*2,l,mid);     //递归构造左子树
        build(root*2+1,mid+1,r); //递归构造右子数
        tree[root].val=tree[root*2].val+tree[root*2+1].val;//存储左右子树的和
    }
}
  • 单点更新线段树

递归更新,递归至要更新的叶子节点,回溯更改该叶子节点会导致其他节点的值

/*id: 待更新节点在原始数组arr中的下标
  addVal: 更新的值(原来的值加上addVal)*/
void add(int root,int id,int addval)  //单点更新 
{
    int mid;
    if (tree[root].l==tree[root].r)
    {
        tree[root
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值