[summary] 线段树

什么是线段树?

线段树是一种二叉树,用于区间搜索等.
常用来处理这样一类问题:在某区间中插入一些线,删除一些线,最后问某点被覆盖多少次.
因此,线段树一般需要支持以下操作:
给某区间增加一个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的操作,同样这里只需要做到需要查询的区间已经更新就够了!

例题:

poj 3468 a simple problem with integers

我的解答

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值