ダイナミック処方セグメントツリー

前提条件ダイナミックオープンポイントがツリーの会長である、それを学習Keqianyuxi会長の木であると考えられています。

達成するための処方箋リストに類似したバイナリツリーのダイナミクスの個人的な理解、左右の息子には2つのポインタがあります。ダイナミックなオープンポイント大体同じように。一例として、最大範囲にするために、セグメントツリーは3つの情報を維持します。

  1. ノードの現在の息子の左ノード番号
  2. 右の息子、現在のノードのノード番号
  3. 間隔の最大値

 最初の貢献、の関数としての貢献

int build(){
	++cnt;
	c[cnt].l = 0;
	c[cnt].r = 0;
	c[cnt].max = -inf;
	return cnt;
}

新しいノードの追加を表す、新たに追加されたノードの子約0(空)、現在のノード番号戻り出ています。新しいノードが増加すると、それは訪問の時から親ノードの下に見つからないしなければならない場合、これは新しい息子ノードを作成する必要があり、その後、親ノード番号は、左または右の息子のノードは、新しいノードの現在の数です。

最初の時間、ルートの必要性は、ルート=ビルド()それのルートとしてこの点を新しいポイントを作成します。

シングルポイントの更新を行う場合、例えば、インデックス位置に指数位置変更、更新機能とセグメントツリーは、次のような

void insert(int l, int r, int k, int ind, int d){
	if (l == r){
		c[k].max += d;
		return;
	}
	int mid = (l + r) >> 1;
	if (ind <= mid){
		if (c[k].l == 0)c[k].l = build();
		insert(l, mid, c[k].l, ind, d);
	}
	else{
		if (c[k].r == 0)c[k].r = build();
		insert(mid + 1, r, c[k].r, ind, d);
	}
	c[k].max = max(c[c[k].l].max, c[c[k].r].max);
}

あなたが更新してリターンにこの点を見つけた場合、それ以外の場合は、二つに時間または間隔を見つけるために探し続ける、この時点での外観は、現在のノードの息子への周りのちょうど散歩に、裁判官に時間がかかるどのセクションであり、 、息子は左ノードを取っていると仮定して、左側の息子の存在する場合は、歩き続け、存在していない、あなたは息子が歩行を継続するために、左のノードを作成する必要があります。残りは、セグメントツリーと同じです。

クエリは類似しているが、それらを繰り返しません。

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof a)
using namespace std;
const int N = 310;
const int inf = 0x7fffffff;
struct p{
	int l, r, max;
};
p c[N * 4];
int root, cnt;
int build(){
	++cnt;
	c[cnt].l = 0;
	c[cnt].r = 0;
	c[cnt].max = -inf;
	return cnt;
}
void insert(int l, int r, int k, int ind, int d){
	if (l == r){
		c[k].max = d;
		return;
	}
	int mid = (l + r) >> 1;
	if (ind <= mid){
		if (c[k].l == 0)c[k].l = build();
		insert(l, mid, c[k].l, ind, d);
	}
	else{
		if (c[k].r == 0)c[k].r = build();
		insert(mid + 1, r, c[k].r, ind, d);
	}
	c[k].max = max(c[c[k].l].max, c[c[k].r].max);
}
int query(int ind, int k, int l, int r){
	if (l == r){
		return c[k].max;
	}
	int mid = (l + r) >> 1;
	if (ind <= mid)return query(ind, c[k].l, l, mid);
	else return query(ind, c[k].r, mid + 1, r);
}
int main()
{
	root = build();
	insert(1, 5, root, 2, 1);
	insert(1, 5, root, 1, 2);
	insert(1, 5, root, 3, 4);
	insert(1, 5, root, 4, 3);
	insert(1, 5, root, 5, 5);
	for (int i = 1; i <= 5; i++){
		printf("%d : %d\n",i, query(i, root, 1, 5));
	}
	return 0;
}

 

公開された204元の記事 ウォン称賛13 ビュー10000 +

おすすめ

転載: blog.csdn.net/weixin_43701790/article/details/104427667
おすすめ