线段树合并

Posted wozaixuexi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树合并相关的知识,希望对你有一定的参考价值。

一开始还以为线段树合并是什么高级操作。

学完后发现其实蛮简单的。

线段树合并,就是把两棵线段树的信息整合到一棵线段树上,只要动态开点递归处理就好了,如图:

技术分享图片

上面这张图展示的就是把左边两棵线段树合并成右边那棵蓝色线段树的过程,还是很好理解的。

下面就是没有那么伪的线段树合并伪代码:

//[l,r]为当前所处理的区间
//x为第一棵线段树当前节点的编号
//y为第二棵线段树当前节点的编号 
function node merge_trees(int l,int r,int x,int y)
{
    if(x==null or y==null) //如果任意一棵线段树的当前节点为空 
    {
        if(x==null) return y; //就直接返回非空节点 
               else return x;
    }
    if(l==r) //如果处理到了区间中只剩一个数了 
    {
        int t = make_new_node(); //新建节点 
        t->val = x->val + y->val; //合并信息 
        t->lson = t->rson = null; //初始左右儿子 
        return t; //返回当前节点 
    }
    int mid = (l + r) / 2 , t = make_new_node(); //求中点、新建节点 
    t->lson = merge_trees(l,mid,x->lson,y->lson); //递归处理左儿子 
    t->rson = merge_trees(mid + 1,r,x->rson,y->rson); //递归处理右儿子 
    t->val = t->lson->val + t->rson->val; //信息上传 
    return t; //记得要返回当前节点 
} 

不难看出,线段树合并的复杂度就是两棵线段树重合的节点的个数。

 

理解一下就好了。

 

例题:bzoj P2212 [Poi2011]Tree Rotations

题解在这里

参考文章在这里

以上是关于线段树合并的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 4756 线段树合并(线段树)

线段树合并

线段树区间合并POJ3667-Hotel

线段树维护区间合并——cf1285E

Luogu4556 雨天的尾巴 树上差分线段树合并

bzoj2733 [ HNOI2012 ] -- 并查集+线段树合并