『权值动态开点线段树』『线段树合并算法』简单理解

权值线段树与动态开点

在正常的线段树中,我们总是以下表来进行线段树的操作。而权值线段树主要用于对具体的权值进行构造线段树,用于权值计数,权值操作等问题。

由于权值太大,我们不再采用完全二叉树的编号方式,使用类似于邻接表一样的存储方式,每一个节点只存储它儿子节点的编号;且只对有用区间进行开点操作,这样复杂度也是 l o g log log级别的。

例如,需要添加权值为为 4 4 4的点,而总区间是 [ 1 , 10 ] [1,10] [1,10];我们只需要开展区间 [ 1 , 10 ] , [ 1 , 5 ] , [ 4 , 5 ] , [ 4 , 4 ] [1,10],[1,5],[4,5],[4,4] [1,10],[1,5],[4,5],[4,4]即可。

代码如下:

void Build(int p,int l,int r,int x,int v)
{
   
    if (l == r) {
    t[p].ans = v; return; }
    int mid = l+r >> 1;
    if (x <= mid)  {
   
        if (t[p].lc == 0) t[p].lc = getnew();
        Build(t[p].lc,l,mid,x,v); 
    }
    else  {
   
        if (t[p].rc == 0) t[p].rc = getnew();
        Build(t[p].rc,mid+1,r,x,v); 
    }
    t[p].ans = t[t[p].lc].ans+t[t[p].rc].ans;
    return;
}
//单点修改位置x为v 动态开点

线段树合并

线段树合并所完成的操作就是:在相同区间内,对应位置相加。

我们可以使用如下方法解决:两个相同区间的节点分别为 p p p q q q,合并区间为 [ l , r ] [l,r] [l,r],若未建立则为0.

  • p p p q q q有其一为0,则另一者为根。
  • l = r l=r l=r,则累加权值,返回p。
  • 合并 p p p的左孩子和 q q q的左孩子, p p p的右孩子和 q q q的右孩子;再讲对应位置的权值相加,返回 p p p
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值