线段树的入门小结

线段树的入门

首先我们应该需要明白线段树可以解决的问题,如 求解数组区间之和,更新区间等

如果使用暴力的方法会超时,这样就引入了线段树这一数据结构线段树的本质是一颗平衡二叉树

线段树的基本性质如下:父亲的区间是[a,b] (c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树需要的空间为数组大小的四倍。

以1到10的区间举例,构造的线段树如下
这里写图片描述

线段树算法包括的主要的函数有三个(和树状数组的一样哎

build(建树函数), update(更新函数), query(查询区间和函数)

先定义下树的结构体

struct node   //这就是一棵树
{
    int left, right;  // 树的子树 
    int sum;    //树的和 
}tree[N];

build函数

void build(int l,int r,int step)
{
    tree[step].left = l;   
    tree[step].right = r;
    if(l == r) return ;   //书已经到了叶子节点。该返回了 
    int mid = (l+r) >> 1; //二分建树
    build(l,mid,step<<1); //递归建立左子树
    build(mid+1,r,step<<1|1);//递归建立右子树
} 

update函数

void update(int l, int r, int value, int step)
{
    if(tree[step].left == tree[step].right) //一直更新到叶子点
        return ;
    int mid = (tree[step].left+tree[step].right)     >> 1;

    //如果所要更新的点的右端小于mid或左端点大于mid,则直接更新l到r的值
    if(r <= mid) update(l,r,value,step<<1);
    else if(l > mid)  update(l,r,value,step<<1|1);
    //如果要更新的点在mid两边,则两边分别更新 
    else {
        update(l,mid,value,step<<1);
        update(mid+1,r,value,step<<1|1);
    }
} 

query函数

int query(int l, int r,int step)
{
    //找到叶子返回值
    if(l==tree[step].left && r==tree[step].right) return tree[step].sum;
    int mid = (tree[step].left+tree[step].right) >> 1;
    //和更新类似
    if(r <= mid) return query(l,r,step<<1);
    if(l > mid) return query(l,r,step<<1|1);
    else
        return query(l,mid,step<<1)+query(mid+1,r,step<<1|1) ;

}

这三个函数就是线段树的精华了2333

帮助大家理解写几道线段树的模板题更好的理解模板
经典入门题HDU1166-敌兵布阵

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值