首页 > 其他 > 详细

线段树合并

时间:2021-08-17 10:30:12      阅读:12      评论:0      收藏:0      [点我收藏+]

线段树合并

用一个新的线段树(也可是原先中的一个)包含两个原线段树的信息便是线段树的合并。

由于基础的线段树son为i*2和i*2+1需4倍空间且下标无法改变的缺点,在需合并的情况下就要使用动态开点线段树。

动态开点线段树

多开一个数组son[N][2]记录每个点的儿子位置。(其实真的很简单:)

void build(int L,int R,int l,int r,int now)
{
    if(l==r)
    {
        t[now]=a[l];
        return;
    }
    int m=l+r>>1;
    if(L<m)
        son[now][0]=++tot,build(L,R,l,mid,tot);
    if(R>m)
        son[now][1]=++tot,build(L,R,mid,r,tot);
    pushup(now);
}

合并

两树维护的内容需具有可合并性才可合并,如区间和、区间最值都可以。

以区间和为例。

int merge(int now1,int now2)///将2号树合并到1号上 
{
    if(!now1||!now2)return now1+now2;
    t[1][now1]+=t[2][now2];
    son[now1][0]=merge(son[now1][0],son[now2][0]);
    son[now2][0]=merge(son[now2][0],son[now2][0]);
    return now1;
}

例题:P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并

 

 

 

线段树合并

原文:https://www.cnblogs.com/29taorz/p/15150386.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!