首页 > 其他分享 >线段树

线段树

时间:2022-12-16 21:04:34浏览次数:47  
标签:结点 线段 信息 插入 区间 节点


这几天把之前学过的线段树又重新系统学习了一下。从网上参考了不少的资料,在尝试

了几个模板之后,最终参考了HH大神的博客。真的是功能齐全又好用。参考文章

​http://www.notonlysuccess.com/index.php/segment-tree-complete/​

 

线段树是一棵二叉树,树中的每一个结点表示了一个区间[a,b]。a,b通常是整数。每一个

叶子节点表示了一个单位区间(长度为1)。对于每一个非叶结点所表示的结点[a,b],其左

儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b](除法去尾取整)。

如下图所示:

线段树_解题报告


线段树适用于和区间统计有关的问题。比如某些数据可以按区间进行划分,按区间动态

进行修改,而且还需要按区间多次进行查询,那么使用线段树可以达到较快查询速度。


线段树共有如下几种:

1.点更新型

对于这种线段树,通常是向线段树中插入点,即对应一个叶子节点的信息,而线段树中

所有节点也都是记录的关于以该点为根的子树中已插入的点的统计信息,询问通常是问

线段树中某个区间对叶子节点的统计信息。

2.区间更新型

对于这种线段树,与第三种有一下共同特点:所有询问和插入操作都是以区间为单位

的,每次都是对一个区间进行操作。每个节点通常会用一个变量来记录以它为跟的子树

的相关信息,在回溯过程中更新此变量。当操作的区间能完整的覆盖一个节点对应的区

间时直接对该节点操作,不再向下操作。

这种线段树还有其独有的特点:当操作一个短线段时,这个短线段在线段树中由上至下

运行到自己对应的位置,这个过程中会经过若干个对应长线段的节点,在经过长线段

时,要把长线段的节点中的信息移动到其两个直接子节点中,然后再继续向下走。这样

可以保证区间信息存储位置的在树中的纵向专一性,即树中节点的直系血亲之间只能有

一个点记录信息。原因如下:在这种线段树的题通常具有以下性质:(1)新插入线段与旧

的线段重叠的部分的信息如果纵向分布,不存储在同一个节点中,则在回溯统计子树信

息过程很难计算。(2)新插入的线段与旧线段的重叠部分可以只保存新线段信息,这样才

能插入过程中完整覆盖一个节点时不用向下操作。

3.区间保留型

这种线段树除了与第二种线段树的共同特点外,还有一个重要特性就是即使旧线段与新

线段重叠了旧线段中的信息也仍然有意义,或者要求插入的线段必须保持在其插入的位

置不向下迭代。

其中保持位置的一种典型情况就是有删除操作。删除并不是随意的删除,每次删除的线

段与原来插入的线段相对应,只删除那些曾经插入过的线段。这种通常我们为了删除时

候方便,在短线段向下运行经过长线段的过程中不会把长线段向下迭代,因为长线段是

要被删除的,如果向下迭代删除时就没有办法对长线段原来的存储节点进行操作,只能

对其许许多多的后代节点中的一些(那些被迭代到了的节点)进行操作,复杂度极高。

这种线段树的题通常信息纵向分布也是可以回溯计算的。


之前写过的线段树各种版本:

。。。。。。 

目前HH版本代码风格:

  • MAXN为最大区间,节点要开为4倍,因为需要2*2^ [log2n] -1个元素 ([log2n]向上取整) ,其中2*2^ [log2n]  -1 <= 4n -1
  • pushup(int root)用于把当前结点的信息更新到父结点
  • pushdown(int root,int L,int R)用于把当前结点的信息更新给儿子结点
  • root表示当前子树的根(root),也就是当前所在的结点

四种线段树题目分类:

  1. 单点更新,只更新叶子节点,利用pushup(int root)函数更新到父节点 ​​HDU_1166_敌兵布阵​​​解题报告:点击打开链接
    ​​​HDU 1754_I Hate It​​​解题报告:点击打开链接
    ​​​HDU 1294_Minimum Inversion Number​​​解题报告:点击打开链接
    ​​​HDU2795_Billboard​​解题报告:点击打开链接
  2. 成段更新(通常这对初学者来说是一道坎),需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候 ​POJ 3468_A Simple Problem with Integers ​​
    解题报告:点击打开链接
    ​​​HDU1698_Just a Hook​​​解题报告:点击打开链接
  3. 区间合并
    这类题目会询问区间中满足条件的连续最长区间,所以PushUp的时候需要对左右儿子的区间进行合并
  4. 扫描线
    这类题目需要将一些操作排序,然后从左到右用一根扫描线(当然是在我们脑子里)扫过去
    最典型的就是矩形面积并,周长并等题

未完待续。。。。。。

 


标签:结点,线段,信息,插入,区间,节点
From: https://blog.51cto.com/ITCharge/5948425

相关文章

  • HDU 4614 ——线段树+二分
    //题意:茜茜学姐的情人节到了!众所周知,茜茜学姐喜欢帅气的学弟,所以她当然有很多学弟送的花瓶,据不完全统计,茜茜学姐有N个花瓶(标号为0~N-1)。当然茜茜学姐也是个魅力四射......
  • ICPC2020 南京J 吉司机线段树
    题目是一个序列。两个操作1对L,R里的所有数字对输入x取max。2询问L,R里某一位二进制位的1的个数。n是正常的200000用线段树来维护两个操作。先考虑第一个操作用吉司机......
  • AcWing 261. 旅馆 【线段树】
    [NOIP2015普及组]推销员题目背景NOIP2015普及组T4题目描述阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧......
  • codeforces 1354D - Multiset (线段树或者2分)
    题目大意:已知一个数列an,我们每次可以添加一个数k,或者把第k大的数字去掉。问我们经过k次操作后,数列中任意1个剩余的数字。n,q<=1e6解题思路:首先最简单的思路是线段树。线段......
  • 线段树专题
    线段树专题线段树与树状数组的视频教程,非常清晰,强烈推荐一、线段树基础1.线段树简介线段树是算法竞赛中常用的用来维护区间信息的数据结构。线段树可以在很小的时间......
  • 线段简化的几种算法
    翻译自:https://www.codeproject.com/Articles/114797/Polyline-Simplification#headingDPN参考:https://www.codeproject.com/Articles/114797/Polyline-Simplification......
  • 线段树优化
    有些修改是无效的修改,对于部分的修改,我们修改是无用的.例子维护一颗线段树,支持单点修改,区间和,区间取模操作.思路显然,如果对于一个修改区间,如果最大值小于这个模数,......
  • 李超线段树
    初学笔记,目前水平仅限于板子。李超线段树可以维护很多直线(或者线段),并可以查询某个点上最高点或者最低点。思想是考虑当前线段可能会更新哪些区间,对于一个区间而言,有一个之......
  • 可持久化Trie and 线段树常见扩展
    可持久化数据结构可持久化Trie思想概述可持久化数据结构,是一种对原本数据结构进行的扩展,可以支持查询以前的历史版本的信息在进行每一次操作的时候,我们都把需要更新的......
  • P3834 【模板】可持久化线段树 2
    【模板】可持久化线段树2题目背景这是个非常经典的可持久化权值线段树入门题——静态区间第\(k\)小。数据已经过加强,请使用可持久化权值线段树。同时请注意常数优化......