线段树知识点

线段树解决的主要问题:1 单点更新,区间查询 2 区间更新,单点查询 3 区间更新,区间查询


线段树的本质是一棵二叉树,线段树的每一个节点记录的是一段区间的信息。
e.g. 对于长度为5的数组a[1]~a[5]
       [1,5]                                          
     
   [1,3]     [4,5]                                              对于任一非叶子节点,若该区间为[L,R],则
    [1,2] [3,3] [4,4] [5,5]                                 左儿子为[L,(L+R)/2]
                                                                  右儿子为[(L+R)/2+1,R]




  对于任一节点a[k],
它的左儿子为a[2*k]
它的右儿子为a[2*k




         线段树空间应开为原数组长度的4倍

             


   课件中的方法:         

lsonrson分辨表示结点的左儿子和右儿子,由于每次传参数的时候都固定是这几个变量,所以可以用预定于比较方便的表示

PushUP(int rt)是把当前结点的信息更新到父结点

PushDown(int rt)是把当前结点的信息更新给儿子结点

建树

void PushUP(int rt) {

MAX[rt] = MAX[rt<<1] + MAX[rt<<1|1];

}//具体问题具体分析

void build(int l,int r,int rt) {

if (l == r) {

scanf("%d",&MAX[rt]);

return ;

}

int m = (l + r) >> 1;

build(lson);

build(rson);

PushUP(rt);

}// build(1,n,1)

更新

void update(int p,int sc,int l,int r,int rt) {更新的输的位置 输入跟新的树

if (l == r) {

MAX[rt] = sc;//具体问题具体分析

return ;

}

int m = (l + r) >> 1;

if (p <= m) update(p , sc , lson);

else update(p , sc , rson);

PushUP(rt);

}

查询

int query(int L,int R,int l,int r,int rt) {

if (L <= l && r <= R) {

return MAX[rt];

}

int m = (l + r) >> 1;

int ret = 0;

if (L <= m) ret = max(ret , query(L , R , lson));具体问题具体分析

if (R > m) ret = max(ret , query(L , R , rson));

return ret;

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值