线段树合并
内容
两颗线段树的合并。
过程
就是遍历线段树,假设 \(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(值域))\)

浙公网安备 33010602011771号