• 线段树入门之夜空星亮


    --------------------------------------------不是能不能办到的问题,既然我已经下定决心要成为海贼王了,如果因此而战死的话,也无所谓了。

    承接上一章节,继续探索线段树丫!

    如何利用线段树进行区间统计?

    假设这13个数为1,2,3,4,1,2,3,4,1,2,3,4,1. (A[1]=1,A[2]=2,......A[13]=1)在区间之后标上该区间的数字之和:

     

    如果要计算[2,12]的和,按照之前的算法:
    [2,12]=[2] + [3,4] + [5,7] + [8,10] + [11,12]
      29  = 2 + 7 + 6 + 7 + 7
    计算5个数的和就可以算出[2,12]的值。

     嘻嘻,下面介绍另一个问题:

    如何进行点修改?

    以上一个图为讨论的基础:

    假设把A[6]+=7 ,看看哪些区间需要修改?[6],[5,6],[5,7],[1,7],[1,13]这些区间全部都需要+7.其余所有区间都不用动。

    于是,这颗线段树中,点修改最多修改5个线段树元素(每层一个)。

    下图中,修改后的元素用蓝色表示。

    一身转战三千里,且去追寻线段树的存储结构:

    线段树是一种二叉树,当然可以像一般的树那样写成结构体,指针什么的。
    但是它的优点是,它也可以用数组来实现树形结构,可以大大简化代码。
    数组形式适合在编程竞赛中使用,在已经知道线段树的最大规模的情况下,直接开足够空间的数组,然后在上面建立线段树。
    简单的记法: 足够的空间 = 数组大小n的四倍。
    实际上足够的空间 =  (n向上扩充到最近的2的某个次方)的两倍。
    举例子:假设数组长度为5,就需要5先扩充成8,8*2=16.线段树需要16个元素。如果数组元素为8,那么也需要16个元素。
    所以线段树需要的空间是n的两倍到四倍之间的某个数,一般就开4*n的空间就好,如果空间不够,可以自己算好最大值来省点空间。
     
    怎么用数组来表示一颗二叉树呢?假设某个节点的编号为v,那么它的左子节点编号为2*v,右子节点编号为2*v+1。
    然后规定根节点为1.这样一颗二叉树就构造完成了。通常2*v在代码中写成 v<<1 。 2*v+1写成 v<<1|1
     
     
  • 相关阅读:
    js定时跳转
    MySQL跨表更新字段 工作记录
    windows下安装phpcms html/ 文件夹不可写的一种错误以及解决方法
    linux清理僵尸进程
    JQuery实现隔行变色和突出显示当前行 效果
    windows下配置lamp环境(4)---安装MySQL数据库5.6
    windows下配置lamp环境(5)---配置MySQL5.6
    windows下配置lamp环境(3)---配置PHP5.4
    windows下配置lamp环境(0)---软件获取
    windows下配置lamp环境(2)---配置Apache服务器2.2.25
  • 原文地址:https://www.cnblogs.com/dragondragon/p/11241773.html
Copyright © 2020-2023  润新知