[模板] 线段树合并

线段树合并

把若干棵叶子节点总数为 \(n\) 的线段树通过某种顺序合并成一棵线段树. 时间复杂度 \(O(n \log n)\).

时间复杂度分析

考虑两颗线段树合并, 复杂度为这两颗线段树的相同节点个数. 这可以看作是删除的节点个数.

那么所有线段树合并, 所有节点最多被删除一次. 时间复杂度即为 \(O(n \log n)\).

线段树合并的空间复杂度也为 \(O(n \log n)\), 而可持久化的线段树合并 (见下) 使用的空间不超过 \(2 \cdot n\log n\).

普通的线段树合并

rt1 变为 rt1rt2 的并.

int merge(int rt1,int rt2){
	if(rt1==0||rt2==0)return rt1+rt2;
	ls(rt1)=merge(ls(rt1),ls(rt2));
	rs(rt1)=merge(rs(rt1),rs(rt2));
	pu(rt1);
	return rt1;
}

可持久化线段树合并

建立新树为两棵树的并.

int merge(int rt1,int rt2){
	if(rt1==0||rt2==0)return rt1+rt2;
	int rt=++pnd;
	ls(rt)=merge(ls(rt1),ls(rt2));
	rs(rt)=merge(rs(rt1),rs(rt2));
	return rt;
}

https://wenku.baidu.com/view/88f4e134e518964bcf847c95.html

posted @ 2019-07-05 20:15  Ubospica  阅读(406)  评论(0编辑  收藏  举报