线段树合并

线段树合并

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

由于基础的线段树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有约会]雨天的尾巴 /【模板】线段树合并

 

 

 

线段树合并

上一篇:数据结构详解


下一篇:synchronized关键字