Skip to content

Persistent Segment Tree #12186

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0457860
Suffix Array and LCP Array Implementation
putul03 Oct 19, 2024
465cea3
Delete divide_and_conquer/suffix_array_lcp.py
putul03 Oct 19, 2024
8ab2927
Add files via upload
putul03 Oct 19, 2024
f5d380a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
819fdc8
Update persistent_segment_tree.py
putul03 Oct 19, 2024
5de6184
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
82270b7
Update persistent_segment_tree.py
putul03 Oct 19, 2024
ff5a9b8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
04b44c4
Update persistent_segment_tree.py
putul03 Oct 19, 2024
0f5718f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
eb9e2b7
Update persistent_segment_tree.py
putul03 Oct 19, 2024
5c605df
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
55e6a87
Update persistent_segment_tree.py
putul03 Oct 19, 2024
eaafd1c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
124b177
Update persistent_segment_tree.py
putul03 Oct 19, 2024
902ed93
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
f64233a
Update persistent_segment_tree.py
putul03 Oct 19, 2024
4484382
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
210e9a2
Update persistent_segment_tree.py
putul03 Oct 19, 2024
fc627f1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
4598bc8
Update persistent_segment_tree.py
putul03 Oct 19, 2024
103651e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
e968d12
Update persistent_segment_tree.py
putul03 Oct 19, 2024
4e95c90
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
9e07fc9
Update persistent_segment_tree.py
putul03 Oct 19, 2024
bcd9f5d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions data_structures/persistent_segment_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from __future__ import annotations

class Node:

Check failure on line 3 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

data_structures/persistent_segment_tree.py:1:1: I001 Import block is un-sorted or un-formatted
def __init__(self, value: int = 0) -> None:
self.value: int = value
self.left: Node | None = None
self.right: Node | None = None

class PersistentSegmentTree:
def __init__(self, arr: list[int]) -> None:
self.n: int = len(arr)
self.roots: list[Node] = []
self.roots.append(self._build(arr, 0, self.n - 1))

def _build(self, arr: list[int], start: int, end: int) -> Node:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/persistent_segment_tree.py, please provide doctest for the function _build

"""
Builds a segment tree from the provided array.
"""
if start == end:
return Node(arr[start])
mid = (start + end) // 2
node = Node()
node.left = self._build(arr, start, mid)
node.right = self._build(arr, mid + 1, end)
node.value = node.left.value + node.right.value
return node

def update(self, version: int, index: int, value: int) -> int:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/persistent_segment_tree.py, please provide doctest for the function update

"""
Updates the value at the given index and returns the new version.
"""
new_root = self._update(self.roots[version], 0, self.n - 1, index, value)
self.roots.append(new_root)
return len(self.roots) - 1

def _update(self, node: Node | None, start: int, end: int, index: int, value: int) -> Node:

Check failure on line 36 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

data_structures/persistent_segment_tree.py:36:89: E501 Line too long (95 > 88)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/persistent_segment_tree.py, please provide doctest for the function _update

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/persistent_segment_tree.py, please provide doctest for the function _update

"""
Updates the node for the specified index and value and returns the new node.
"""
if node is None: # Handle the None case
node = Node() # Create a new node if None

if start == end:
return Node(value)

mid = (start + end) // 2
new_node = Node()

if index <= mid:
new_node.left = self._update(node.left, start, mid, index, value)
new_node.right = node.right # Ensure right node is the same as the original
else:
new_node.left = node.left # Ensure left node is the same as the original
new_node.right = self._update(node.right, mid + 1, end, index, value)

new_node.value = new_node.left.value + (new_node.right.value if new_node.right else 0)

Check failure on line 56 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

data_structures/persistent_segment_tree.py:56:89: E501 Line too long (94 > 88)

return new_node

def query(self, version: int, left: int, right: int) -> int:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/persistent_segment_tree.py, please provide doctest for the function query

"""
Queries the sum in the given range for the specified version.
"""
return self._query(self.roots[version], 0, self.n - 1, left, right)

def _query(self, node: Node | None, start: int, end: int, left: int, right: int) -> int:

Check failure on line 66 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

data_structures/persistent_segment_tree.py:66:89: E501 Line too long (92 > 88)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/persistent_segment_tree.py, please provide doctest for the function _query

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/persistent_segment_tree.py, please provide doctest for the function _query

"""
Queries the sum of values in the range [left, right] for the given node.
"""
if node is None or left > end or right < start:
return 0
if left <= start and right >= end:
return node.value
mid = (start + end) // 2
return (self._query(node.left, start, mid, left, right) +
self._query(node.right, mid + 1, end, left, right))

# Running the doctests
if __name__ == "__main__":
import doctest
print("Running doctests...")
result = doctest.testmod()
print(f"Ran {result.attempted} tests, {result.failed} failed.")
Loading