线段树合并浅谈

Posted katoukatou

tags:

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

对于某些对子树的统计问题,我们固然可以用DSU on Tree来解决,但是一旦带上修改,甚至是加上历史化版本的查询,我们就不得不求助于其他的算法,本篇将对线段树合并进行讲解


线段树合并一般用于对子树的统计,一般的套路就是对树的每一个节点都开上一颗动态开点线段树,然后统计子树信息时,合并所有儿子信息,统计答案,然后继续向上走;

例题也很多,比如[USACO17JAN]Promotion Counting晋升者计数,【NOIP2016 DAY1】天天爱跑步等等都可以这样乱搞,实现起来也非常好理解,这是针对天天爱跑步类型(权值线段树)的(Merge)代码:

(code):

void merge(int &x,int y)
{
    if(!x||!y){x=x+y;return;}
    sum[x]+=sum[y];
    merge(ls[x],ls[y]);
    merge(rs[x],rs[y]);
}

如果希望改为维护历史版本,可以这样改:

int merge(int x,int y)
{
    if(!x||!y){ return x+y;return;}
    int p=++tot;
    ls[p]=merge(ls[x],ls[y]);
    rs[p]=merge(rs[x],rs[y]);
    sum[p]=sum[ls[p]]+sum[rs[p]]
    return p;
}

简单好写,易于理解

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

浅谈zkw线段树(by Shine_hale)

线段树合并

浅谈二维线段树的几种不同的写法

线段树合并

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

浅谈线段树