単純なセグメントツリーのマージ

理解

名前が示すように、2つの線分ツリーの情報をマージすることです。

暴力的なマージは良い考えです。2本の木を一緒に横断するだけです。複雑さオン)

ただし、多くの場合、いっぱいになっていない2つの線分ツリーをマージする必要があり(ここで「いっぱいになっていない」とは、一部の間隔がまったく使用されていないことを意味します)、空間と時間が経過しません。

したがって、いくつかの最適化が使用されます。

アイデア

スペースを最適化する方法は?非常にシンプルでダイナミックなオープニングポイント。

(ここではリンクを開きません。動的に開き、理解している場合はスキップします。

実際、各ノードの左と右の息子を記録することであり(直接アクセスするためにid * 2、id * 2 + 1を使用しなくなりました)、初期値はゼロです。挿入する必要がある場合は、割り当てられます。 2つの新しいポイント(開始ポイントと呼ばれます)に、クエリを開く必要はありません。特別な判断を行うだけです。

完了)

動的な開始点を使用した後、ブルートフォーストラバーサルとマージします。

inline int mergg(int x,int y,int l,int r){
	if(!x||!y)return x|y; //两节点其中一个为零,另一个补上去
	int mid=(l+r)>>1;
	t[x].ls=mergg(t[x].ls,t[y].ls,l,mid),t[y].ls=0; //合并左子树
	t[x].rs=mergg(t[x].rs,t[y].rs,mid+1,r),t[y].rs=0; //合并右子树
	.../*此处合并两点信息*/
	return x;
}

O(n)のように見えますが、(ほとんどの問題で)マージされたツリーの合計サイズが制限されている場合、全体の複雑さはO(nlogn)非動的なものO(n ^ 2)よりはるかに高速です

質問の例:ZZHトラベル

おすすめ

転載: blog.csdn.net/weixin_43960287/article/details/110474047