首页 > 其他 > 详细

线段树合并浅谈

时间:2018-10-27 01:21:57      阅读:228      评论:0      收藏:0      [点我收藏+]

对于某些对子树的统计问题,我们固然可以用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;
}

简单好写,易于理解

线段树合并浅谈

原文:https://www.cnblogs.com/KatouKatou/p/9859459.html

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