def optimal_subarray(A: list[int]) -> tuple[int, int, int]:
"""
Finds the indices (i, j) of the contiguous subarray with the minimum sum
and returns the sum of that subarray in O(n) time using a divide-and-conquer approach.
Args:
- A: List[int], array of integers representing the card costs.
Returns:
- (i, j, min_sum): A tuple where i is the start index, j is the end index, and min_sum is the minimum sum.
"""
# Call the recursive function to calculate the best subarray
return find_min_subarray(A, 0, len(A) - 1)
def find_min_subarray(A: list[int], L: int, R: int) -> tuple[int, int, int, int, int, int]:
"""
Recursive function to find the minimum sum subarray in A[L..R].
Returns:
- (i, j, min_sum, total_sum, prefix_min, suffix_min)
where (i, j) are the indices of the minimum sum subarray,
min_sum is the sum of that subarray,
total_sum is the sum of the whole array A[L..R],
prefix_min is the minimum prefix sum of A[L..R],
suffix_min is the minimum suffix sum of A[L..R].
"""
# Base case: only one element
if L == R:
return (L, R, A[L], A[L], A[L], A[L])
# Divide step: Find the middle index
M = (L + R) // 2
# Conquer step: Recursively find the minimum subarrays in the left and right halves
(i_L, j_L, min_L, total_L, prefix_L, suffix_L) = find_min_subarray(A, L, M)
(i_R, j_R, min_R, total_R, prefix_R, suffix_R) = find_min_subarray(A, M + 1, R)
# Combine step: Calculate the crossing subarray
cross_sum = suffix_L + prefix_R
# Determine the best crossing subarray indices
left_suffix_sum = 0
left_suffix_min = float('inf')
left_suffix_index = M
for i in range(M, L - 1, -1):
left_suffix_sum += A[i]
if left_suffix_sum < left_suffix_min:
left_suffix_min = left_suffix_sum
left_suffix_index = i
right_prefix_sum = 0
right_prefix_min = float('inf')
right_prefix_index = M + 1
for j in range(M + 1, R + 1):
right_prefix_sum += A[j]
if right_prefix_sum < right_prefix_min:
right_prefix_min = right_prefix_sum
right_prefix_index = j
# Cross indices and sum
i_C = left_suffix_index
j_C = right_prefix_index
min_C = cross_sum
# Calculate total, prefix, and suffix for the combined array
total_sum = total_L + total_R
prefix_min = min(prefix_L, total_L + prefix_R)
suffix_min = min(suffix_R, total_R + suffix_L)
# Find the best of the left, right, and cross subarrays
if min_L <= min_R and min_L <= min_C:
return (i_L, j_L, min_L, total_sum, prefix_min, suffix_min)
elif min_R <= min_L and min_R <= min_C:
return (i_R, j_R, min_R, total_sum, prefix_min, suffix_min)
else:
return (i_C, j_C, min_C, total_sum, prefix_min, suffix_min)
# Example usage:
A = [4,-10,3,-5,6,-2,-8,7,-3,5,-6,2]
start_index, end_index, min_sum, _, _, _ = optimal_subarray(A)
print(f"Optimal subarray is from index {start_index} to {end_index} with a minimum sum of {min_sum}.")
ZGVmIG9wdGltYWxfc3ViYXJyYXkoQTogbGlzdFtpbnRdKSAtPiB0dXBsZVtpbnQsIGludCwgaW50XToKICAgICIiIgogICAgRmluZHMgdGhlIGluZGljZXMgKGksIGopIG9mIHRoZSBjb250aWd1b3VzIHN1YmFycmF5IHdpdGggdGhlIG1pbmltdW0gc3VtCiAgICBhbmQgcmV0dXJucyB0aGUgc3VtIG9mIHRoYXQgc3ViYXJyYXkgaW4gTyhuKSB0aW1lIHVzaW5nIGEgZGl2aWRlLWFuZC1jb25xdWVyIGFwcHJvYWNoLgogICAgCiAgICBBcmdzOgogICAgLSBBOiBMaXN0W2ludF0sIGFycmF5IG9mIGludGVnZXJzIHJlcHJlc2VudGluZyB0aGUgY2FyZCBjb3N0cy4KICAgIAogICAgUmV0dXJuczoKICAgIC0gKGksIGosIG1pbl9zdW0pOiBBIHR1cGxlIHdoZXJlIGkgaXMgdGhlIHN0YXJ0IGluZGV4LCBqIGlzIHRoZSBlbmQgaW5kZXgsIGFuZCBtaW5fc3VtIGlzIHRoZSBtaW5pbXVtIHN1bS4KICAgICIiIgogICAgIyBDYWxsIHRoZSByZWN1cnNpdmUgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBiZXN0IHN1YmFycmF5CiAgICByZXR1cm4gZmluZF9taW5fc3ViYXJyYXkoQSwgMCwgbGVuKEEpIC0gMSkKCgpkZWYgZmluZF9taW5fc3ViYXJyYXkoQTogbGlzdFtpbnRdLCBMOiBpbnQsIFI6IGludCkgLT4gdHVwbGVbaW50LCBpbnQsIGludCwgaW50LCBpbnQsIGludF06CiAgICAiIiIKICAgIFJlY3Vyc2l2ZSBmdW5jdGlvbiB0byBmaW5kIHRoZSBtaW5pbXVtIHN1bSBzdWJhcnJheSBpbiBBW0wuLlJdLgogICAgCiAgICBSZXR1cm5zOgogICAgLSAoaSwgaiwgbWluX3N1bSwgdG90YWxfc3VtLCBwcmVmaXhfbWluLCBzdWZmaXhfbWluKQogICAgICB3aGVyZSAoaSwgaikgYXJlIHRoZSBpbmRpY2VzIG9mIHRoZSBtaW5pbXVtIHN1bSBzdWJhcnJheSwKICAgICAgbWluX3N1bSBpcyB0aGUgc3VtIG9mIHRoYXQgc3ViYXJyYXksCiAgICAgIHRvdGFsX3N1bSBpcyB0aGUgc3VtIG9mIHRoZSB3aG9sZSBhcnJheSBBW0wuLlJdLAogICAgICBwcmVmaXhfbWluIGlzIHRoZSBtaW5pbXVtIHByZWZpeCBzdW0gb2YgQVtMLi5SXSwKICAgICAgc3VmZml4X21pbiBpcyB0aGUgbWluaW11bSBzdWZmaXggc3VtIG9mIEFbTC4uUl0uCiAgICAiIiIKICAgICMgQmFzZSBjYXNlOiBvbmx5IG9uZSBlbGVtZW50CiAgICBpZiBMID09IFI6CiAgICAgICAgcmV0dXJuIChMLCBSLCBBW0xdLCBBW0xdLCBBW0xdLCBBW0xdKQoKICAgICMgRGl2aWRlIHN0ZXA6IEZpbmQgdGhlIG1pZGRsZSBpbmRleAogICAgTSA9IChMICsgUikgLy8gMgoKICAgICMgQ29ucXVlciBzdGVwOiBSZWN1cnNpdmVseSBmaW5kIHRoZSBtaW5pbXVtIHN1YmFycmF5cyBpbiB0aGUgbGVmdCBhbmQgcmlnaHQgaGFsdmVzCiAgICAoaV9MLCBqX0wsIG1pbl9MLCB0b3RhbF9MLCBwcmVmaXhfTCwgc3VmZml4X0wpID0gZmluZF9taW5fc3ViYXJyYXkoQSwgTCwgTSkKICAgIChpX1IsIGpfUiwgbWluX1IsIHRvdGFsX1IsIHByZWZpeF9SLCBzdWZmaXhfUikgPSBmaW5kX21pbl9zdWJhcnJheShBLCBNICsgMSwgUikKCiAgICAjIENvbWJpbmUgc3RlcDogQ2FsY3VsYXRlIHRoZSBjcm9zc2luZyBzdWJhcnJheQogICAgY3Jvc3Nfc3VtID0gc3VmZml4X0wgKyBwcmVmaXhfUgoKICAgICMgRGV0ZXJtaW5lIHRoZSBiZXN0IGNyb3NzaW5nIHN1YmFycmF5IGluZGljZXMKICAgIGxlZnRfc3VmZml4X3N1bSA9IDAKICAgIGxlZnRfc3VmZml4X21pbiA9IGZsb2F0KCdpbmYnKQogICAgbGVmdF9zdWZmaXhfaW5kZXggPSBNCiAgICBmb3IgaSBpbiByYW5nZShNLCBMIC0gMSwgLTEpOgogICAgICAgIGxlZnRfc3VmZml4X3N1bSArPSBBW2ldCiAgICAgICAgaWYgbGVmdF9zdWZmaXhfc3VtIDwgbGVmdF9zdWZmaXhfbWluOgogICAgICAgICAgICBsZWZ0X3N1ZmZpeF9taW4gPSBsZWZ0X3N1ZmZpeF9zdW0KICAgICAgICAgICAgbGVmdF9zdWZmaXhfaW5kZXggPSBpCgogICAgcmlnaHRfcHJlZml4X3N1bSA9IDAKICAgIHJpZ2h0X3ByZWZpeF9taW4gPSBmbG9hdCgnaW5mJykKICAgIHJpZ2h0X3ByZWZpeF9pbmRleCA9IE0gKyAxCiAgICBmb3IgaiBpbiByYW5nZShNICsgMSwgUiArIDEpOgogICAgICAgIHJpZ2h0X3ByZWZpeF9zdW0gKz0gQVtqXQogICAgICAgIGlmIHJpZ2h0X3ByZWZpeF9zdW0gPCByaWdodF9wcmVmaXhfbWluOgogICAgICAgICAgICByaWdodF9wcmVmaXhfbWluID0gcmlnaHRfcHJlZml4X3N1bQogICAgICAgICAgICByaWdodF9wcmVmaXhfaW5kZXggPSBqCgogICAgIyBDcm9zcyBpbmRpY2VzIGFuZCBzdW0KICAgIGlfQyA9IGxlZnRfc3VmZml4X2luZGV4CiAgICBqX0MgPSByaWdodF9wcmVmaXhfaW5kZXgKICAgIG1pbl9DID0gY3Jvc3Nfc3VtCgogICAgIyBDYWxjdWxhdGUgdG90YWwsIHByZWZpeCwgYW5kIHN1ZmZpeCBmb3IgdGhlIGNvbWJpbmVkIGFycmF5CiAgICB0b3RhbF9zdW0gPSB0b3RhbF9MICsgdG90YWxfUgogICAgcHJlZml4X21pbiA9IG1pbihwcmVmaXhfTCwgdG90YWxfTCArIHByZWZpeF9SKQogICAgc3VmZml4X21pbiA9IG1pbihzdWZmaXhfUiwgdG90YWxfUiArIHN1ZmZpeF9MKQoKICAgICMgRmluZCB0aGUgYmVzdCBvZiB0aGUgbGVmdCwgcmlnaHQsIGFuZCBjcm9zcyBzdWJhcnJheXMKICAgIGlmIG1pbl9MIDw9IG1pbl9SIGFuZCBtaW5fTCA8PSBtaW5fQzoKICAgICAgICByZXR1cm4gKGlfTCwgal9MLCBtaW5fTCwgdG90YWxfc3VtLCBwcmVmaXhfbWluLCBzdWZmaXhfbWluKQogICAgZWxpZiBtaW5fUiA8PSBtaW5fTCBhbmQgbWluX1IgPD0gbWluX0M6CiAgICAgICAgcmV0dXJuIChpX1IsIGpfUiwgbWluX1IsIHRvdGFsX3N1bSwgcHJlZml4X21pbiwgc3VmZml4X21pbikKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIChpX0MsIGpfQywgbWluX0MsIHRvdGFsX3N1bSwgcHJlZml4X21pbiwgc3VmZml4X21pbikKCgojIEV4YW1wbGUgdXNhZ2U6CkEgPSBbNCwtMTAsMywtNSw2LC0yLC04LDcsLTMsNSwtNiwyXQpzdGFydF9pbmRleCwgZW5kX2luZGV4LCBtaW5fc3VtLCBfLCBfLCBfID0gb3B0aW1hbF9zdWJhcnJheShBKQpwcmludChmIk9wdGltYWwgc3ViYXJyYXkgaXMgZnJvbSBpbmRleCB7c3RhcnRfaW5kZXh9IHRvIHtlbmRfaW5kZXh9IHdpdGggYSBtaW5pbXVtIHN1bSBvZiB7bWluX3N1bX0uIik=