线段树简介及实现

线段树

一 线段树简介

 线段树是一种数据结构,对于RMQ,RSQ问题可以达到O(log(n))的区间修改,同时还支持多种加乘的操作,是一种常见的数据结构

二 线段树的数据结构

 在这里我们可以设计一个结构体去存储一个节点的信息,有左边界,右边界,懒惰标记,区间内数之和等附加数据功能

对于单点的数据,他的左边界等于右边界

 懒惰标记是我们实现O(logn)区间修改的关键点。即如果我们要修改一个区间内的数,那么我们只要修改管理这个大区间的点即可,没有必要对它管理的分支进行进一步操作,等到下一步需要操作时在将这个懒惰标记向下传导。

三 线段树的代码实现

1数据结构

 struct SergmentNode
{
   int l;
   int r;
   int lazy;
   int sum;
}elem[N];

2 建树

void bulid(int p,int r,int l)
{
    elem[p].l = l;
    elem[p].r = r;
    if(l==r) elem[p].sum = number[r];
    else
    {
        int mid = (l+r)>>1;
        bulid(ls(p), l, mid);
        bulid(rs(p), mid+1, l);
        elem[p].sum = elem[rs(p)].sum + elem[ls(p)].sum;
    }
}

3 传导懒惰标记

void spread(int p)
{
    if(elem[p].lazy)
    {
        elem[ls(p)].sum += (elem[ls(p)].r - elem[ls(p)].l + 1)*elem[p].lazy;
        elem[rs(p)].sum += (elem[rs(p)].r - elem[rs(p)].l + 1)*elem[p].lazy;
        elem[ls(p)].lazy += elem[p].lazy; // 增加标记
        elem[rs(p)].lazy += elem[p].lazy;
        elem[p].lazy = 0;// 传导后直接清空慵懒标记
    }
}

4 区间修改

void update(int p,int l,int r,int add)
{
    if(l<=elem[p].l&&r>=elem[p].r)
    {
        elem[p].sum += (elem[p].r - elem[p].l + 1)*add;
        elem[p].lazy += add;
        return;
    }
    // 如果这个区间被包含在要修改的区间内
    int mid = (elem[p].r + elem[p].l)>>1;
    if(l <= mid) update(ls(p), l, r, add);
    if(r >= mid) update(rs(p), l, r, add);
    elem[p].sum += elem[ls(p)].sum + elem[rs(p)].sum;
    // 增加和数
}

5 区间查询

int ask(int p,int l,int r)
{
    if(l<=elem[p].l&&r>=elem[p].r) return elem[p].sum;
    spread(p);
    int mid = (elem[p].r+elem[p].l)>>1;
    int ans = 0;
    if(l <= mid) ans+=ask(ls(p), l, r);
    if(r >= mid) ans+=ask(rs(p), l, r);
    return ans;
}

写在最后,考试周,写的匆忙,勿怪

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值