Skip to content
Open
Changes from 17 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
110 changes: 110 additions & 0 deletions data_structures/persistent_segment_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
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.

>>> pst = PersistentSegmentTree([1, 2, 3, 4])
>>> root = pst._build([1, 2, 3, 4], 0, 3)
>>> root.value # Sum of the whole array
10
>>> root.left.value # Sum of the left half
3
>>> root.right.value # Sum of the right half
7
"""
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.

>>> pst = PersistentSegmentTree([1, 2, 3, 4])
>>> version_1 = pst.update(0, 1, 5) # Update index 1 to 5
>>> pst.query(version_1, 0, 3) # Query sum of all elements in new version
13
>>> pst.query(0, 0, 3) # Original version remains unchanged
10
>>> version_2 = pst.update(version_1, 3, 6) # Update index 3 to 6 in version_1
>>> pst.query(version_2, 0, 3) # Query sum of all elements in newest version
15
"""
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 55 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

data_structures/persistent_segment_tree.py:55: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

if node is None:
raise ValueError("Cannot update a None node")

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
else:
new_node.left = node.left
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 72 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

data_structures/persistent_segment_tree.py:72: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.

>>> pst = PersistentSegmentTree([1, 2, 3, 4])
>>> pst.query(0, 0, 3) # Sum of all elements in original version
10
>>> pst.query(0, 1, 2) # Sum of elements at index 1 and 2 in original version
5
>>> version_1 = pst.update(0, 1, 5) # Update index 1 to 5
>>> pst.query(version_1, 0, 3) # Sum of all elements in new version
13
>>> pst.query(version_1, 1, 2) # Sum of elements at index 1 and 2 in new version

Check failure on line 88 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

data_structures/persistent_segment_tree.py:88:89: E501 Line too long (89 > 88)
8
"""
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 93 in data_structures/persistent_segment_tree.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

data_structures/persistent_segment_tree.py:93: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

if node is None:
return 0

if 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