线段树合并

内容

两颗线段树的合并。

过程

就是遍历线段树,假设 \(x\) 为当前遍历到的节点。

  • 如果两颗线段树在这个位置都有信息,那么累加继续遍历。
  • 否则就直接接上有信息的节点,返回。

代码

void merge(int &x,int y,int l,int r)
{
    if(!x||!y)return x=x+y,void();
    if(l==r)return;
    tr[x].val+=tr[y].val;
    int mid=(l+r)/2;
    merge(tr[x].ls,tr[y].ls,l,mid);
    merge(tr[x].rs,tr[y].rs,mid+1,r);
}

时间复杂度

均摊\(O(nlogV)\),\(V\)是值域。

证明

博客园图片

比如说,有蓝色线条标记的是一号线段树,黄色是二号。
一号和二号有合并。
先画出所有线段树合并后的样子,再将合并的步骤中所经过的节点的次数标出。
你有可能会发现每次合并后,每个节点所经过的次数小于等于插入节点的次数,故均摊和插入时间复杂度样\(O(nlog(值域))\)

posted @ 2025-12-16 20:37  xthought  阅读(2)  评论(0)    收藏  举报