Skip to content

Commit

Permalink
Update 029.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Reputeless committed May 4, 2022
1 parent 059ab00 commit b5315d1
Showing 1 changed file with 28 additions and 27 deletions.
55 changes: 28 additions & 27 deletions 029.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public:

LazySegmentTree() = default;

// ツリーの初期化(単位元は 0)
explicit LazySegmentTree(size_t size)
{
// size 以上である 2 のべき乗数を求めて m_size に代入する
Expand All @@ -33,11 +34,11 @@ public:
update(begin, end, value, 0, 0, m_size);
}

// クエリ対象区間 [begin, end) における最大値を求める
int rangeMax(size_t begin, size_t end)
// 区間クエリ(対象区間 [begin, end) における最大値を求める
int query(size_t begin, size_t end)
{
// rangeMax(クエリ対象区間, 0, 全区間);
return rangeMax(begin, end, 0, 0, m_size);
return query(begin, end, 0, 0, m_size);
}

private:
Expand All @@ -64,63 +65,63 @@ private:
}
}

// クエリ対象区間 [begin, end) を value に更新する.
// ni: 確認するノードのインデックス. そのノードの管理区間は [sBegin, sEnd)
void update(size_t begin, size_t end, int value, size_t ni, size_t sBegin, size_t sEnd)
// 区間クエリ(対象区間 [begin, end) における最大値を求める)
// ni: 確認するノードのインデックス. そのノードの管理区間は [nBegin, nEnd)
void update(size_t begin, size_t end, int value, size_t ni, size_t nBegin, size_t nEnd)
{
// クエリ対象区間が管理区間と無関係なら
if ((sEnd <= begin) || (end <= sBegin))
if ((nEnd <= begin) || (end <= nBegin))
{
return; // 何もしない
}

propagate(ni);

// 管理区間のすべてがクエリ対象区間に含まれていれば
if ((begin <= sBegin) && (sEnd <= end))
if ((begin <= nBegin) && (nEnd <= end))
{
// 現在のノードの遅延評価の値に value をセット
m_lazyNodes[ni] = value;

propagate(ni);

return;
}

// update(クエリ対象区間, value, 子ノード(左) のインデックス, 子ノード(左) の管理区間)
update(begin, end, value, (ni * 2 + 1), sBegin, (sBegin + sEnd) / 2);
update(begin, end, value, (ni * 2 + 1), nBegin, (nBegin + nEnd) / 2);

// update(クエリ対象区間, value, 子ノード(右) のインデックス, 子ノード(右) の管理区間)
update(begin, end, value, (ni * 2 + 2), (sBegin + sEnd) / 2, sEnd);
update(begin, end, value, (ni * 2 + 2), (nBegin + nEnd) / 2, nEnd);

// 現在のノードの計算済みの値を、子ノード (左, 右) の計算済みの値をもとに更新
m_nodes[ni] = std::max(m_nodes[ni * 2 + 1], m_nodes[ni * 2 + 2]);
}

// クエリ対象区間 [begin, end) における最大値を求める.
// ni: 確認するノードのインデックス. そのノードの管理区間は [sBegin, sEnd)
int rangeMax(size_t begin, size_t end, size_t ni, size_t sBegin, size_t sEnd)
// ni: 確認するノードのインデックス. そのノードの管理区間は [nBegin, nEnd)
int query(size_t begin, size_t end, size_t ni, size_t nBegin, size_t nEnd)
{
// クエリ対象区間が管理区間と無関係なら
if ((sEnd <= begin) || (end <= sBegin))
if ((nEnd <= begin) || (end <= nBegin))
{
return 0; // 空の値を返す
}

propagate(ni);

// 管理区間のすべてがクエリ対象区間に含まれていれば
if ((begin <= sBegin) && (sEnd <= end))
if ((begin <= nBegin) && (nEnd <= end))
{
return m_nodes[ni];
}

// rangeMax(クエリ対象区間, 子ノード(左) のインデックス, 子ノード(左) の管理区間)
const int lc = rangeMax(begin, end, (ni * 2 + 1), sBegin, (sBegin + sEnd) / 2);
// rangeMax(クエリ対象区間, 子ノード(右) のインデックス, 子ノード(右) の管理区間)
const int rc = rangeMax(begin, end, (ni * 2 + 2), (sBegin + sEnd) / 2, sEnd);
// query(クエリ対象区間, 子ノード(左) のインデックス, 子ノード(左) の管理区間)
const int lc = query(begin, end, (ni * 2 + 1), nBegin, (nBegin + nEnd) / 2);

// query(クエリ対象区間, 子ノード(右) のインデックス, 子ノード(右) の管理区間)
const int rc = query(begin, end, (ni * 2 + 2), (nBegin + nEnd) / 2, nEnd);

return std::max(lc, rc);
}

Expand Down Expand Up @@ -155,8 +156,8 @@ int main()
--L;

// クエリ対象区間の現在の高さ
const int oldH = segTree.rangeMax(L, R);
const int oldH = segTree.query(L, R);

// クエリ対象区間の新しい高さ (+1)
const int newH = (oldH + 1);

Expand Down

0 comments on commit b5315d1

Please sign in to comment.