线段树合并浅谈
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;
}
简单好写,易于理解
以上是关于线段树合并浅谈的主要内容,如果未能解决你的问题,请参考以下文章