博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[summary] 线段树
阅读量:7114 次
发布时间:2019-06-28

本文共 1634 字,大约阅读时间需要 5 分钟。

hot3.png

什么是线段树?

线段树是一种二叉树,用于区间搜索等.

常用来处理这样一类问题:在某区间中插入一些线,删除一些线,最后问某点被覆盖多少次.
因此,线段树一般需要支持以下操作:
给某区间增加一个delta值,查询某点的覆盖次数,查询某区间被覆盖次数之和....等

线段树的构建?

线段树是一种二叉搜索树,它的每个结点表示一个区间,根结点表示最大的区间,左儿子表示根节点表示区间的左半区间,右儿子表示右半区间.

所以线段树的结点常常包括:两个值left right,分别记录区间左右边界; sum记录区间覆盖次数之和....根据不一样的题目,可能有不一样的改动.
一般的结点就像这样:

class node{    int left, right;    int sum;};

线段树,需要被构建.当left == right,区间表示一个点,sum就是点的值.否则,sum为左儿子与右儿子sum的和.

void build(int l, int r, node &father){    father.left = l;    father.right = r;    if(l == r)    {        father.sum = n[r];        return;    }    int mid = (l + r) >> 1;    build(l, mid, node leftson);    build(mid + 1, r, node rightson);    father.sum = leftson.sum + rightson.sum;    return;}

线段树的一般实现:

需要支持ask(l, r, i)操作, 询问结点区间i区间[l,r]中的部分的Sum. 如果区间i与该区间没重叠部分,Sum就是0; 如果区间i被完全覆盖,Sum就是i的sum; 否则区间i与该区间相交,则sum为i左右儿子在区间[l, r]的Sum之和,需要递归的进行计算.

int ans;void ask(int l, int r, node father){    if father not in [l, r]        then return    if father in [l, r]        then ans <- ans + father.sum             return    ask(l, r, leftson)    ask(l, r, rightson)    father.sum <- leftson.sum + rightson.sum    return}

还需要支持update(l, r, i, delta),区间i在区间[l, r]中的部分的每个点覆盖次数加delta.这里与上面ask类似.

线段树的延迟标记

我们不需要每次进行update就对所有的结点进行处理,而是可以将delta保存起来,这样多个delta可以一起计算.

可以想象一下update(l,r,i,1),update(l,r,i,2),update(l,r,i,4);我们不需要每次都计算所有结点,将delta的总和1+2+4记录在结点i中,并更新[l,r]的sum并不更新子节点的sum,需要时(*)计算一次update(l,r,i,7)即可.
需要在node中增加一个toadd来记录node所表示的区间没有增加的delta的总和.
*什么是"需要时"?
如果对区间[l,r]进行ask,显然没有问题,因为我们每次都更新了[l,r]sum值.但是如果ask[l,r]区间的一部分,则有问题,因为还没有加上toadd,此时需要将[l,r]区间进行加toadd的操作,同样这里只需要做到需要查询的区间已经更新就够了!

例题:

转载于:https://my.oschina.net/locusxt/blog/182454

你可能感兴趣的文章
Blockchain和Tangle哪一个是未来?
查看>>
github 上有趣又实用的前端项目(持续更新,欢迎补充)
查看>>
【Under-the-hood-ReactJS-Part6】React源码解读
查看>>
matlab绘制peano(皮亚诺)曲线和koch(科赫曲线,雪花曲线)分形曲线
查看>>
Mybatis之设计模式之迭代器模式
查看>>
小程序TAB列表切换内容动态变化,scrollview高度根据内容动态获取
查看>>
swoole_table 实现原理剖析
查看>>
你需要知道面试中的10个JavaScript概念
查看>>
Java源码阅读之HashMap - JDK1.8
查看>>
Dell服务器系统安装后无法正常进入系统
查看>>
Silverlight/Windows8/WPF/WP7/HTML5周学习导读(9月17日-9月23日)
查看>>
Tap-Ahead:让移动搜索更加便捷的解决之道
查看>>
华为vlan划分,单臂路由以及静态路由
查看>>
3.VMware vsphere 5.0新体验-安装VMware Center
查看>>
趣题: 一道面试题的解法
查看>>
Android应用程序启动过程源代码分析(5)
查看>>
查询整个数据库中某个特定值所在的表和字段的方法
查看>>
在存储过程中编写正确的事务处理代码(SQL Server 2000 & 2005)
查看>>
数据库邮件
查看>>
adstrtal.sh报超时错误 ERROR : Timed out( 100000 ): Interrupted Exception
查看>>