Skip to content

Commit 258f131

Browse files
authored
Update minimum-sum-of-values-by-dividing-array.py
1 parent b575b96 commit 258f131

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

Python/minimum-sum-of-values-by-dividing-array.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,71 @@ def mask(cnt, l):
5858
return dp[-1] if dp[-1] != INF else -1
5959

6060

61+
# Time: O(n * m * (logn + logr)), r = max(nums)
62+
# Space: O(n + logr)
63+
import collections
64+
65+
66+
# dp, sparse table
67+
class Solution2(object):
68+
def minimumValueSum(self, nums, andValues):
69+
"""
70+
:type nums: List[int]
71+
:type andValues: List[int]
72+
:rtype: int
73+
"""
74+
INF = float("inf")
75+
# RMQ - Sparse Table
76+
# Template: https://github.com/kamyu104/GoogleCodeJam-Farewell-Rounds/blob/main/Round%20D/genetic_sequences2.py3
77+
# Time: ctor: O(NlogN) * O(fn)
78+
# query: O(fn)
79+
# Space: O(NlogN)
80+
class SparseTable(object):
81+
def __init__(self, arr, fn):
82+
self.fn = fn
83+
self.bit_length = [0]
84+
n = len(arr)
85+
k = n.bit_length()-1 # log2_floor(n)
86+
for i in xrange(k+1):
87+
self.bit_length.extend(i+1 for _ in xrange(min(1<<i, (n+1)-len(self.bit_length))))
88+
self.st = [[0]*n for _ in xrange(k+1)]
89+
self.st[0] = arr[:]
90+
for i in xrange(1, k+1): # Time: O(NlogN) * O(fn)
91+
for j in xrange((n-(1<<i))+1):
92+
self.st[i][j] = fn(self.st[i-1][j], self.st[i-1][j+(1<<(i-1))])
93+
94+
def query(self, L, R): # Time: O(fn)
95+
i = self.bit_length[R-L+1]-1
96+
return self.fn(self.st[i][L], self.st[i][R-(1<<i)+1])
97+
98+
dp = [INF]*(len(nums)+1)
99+
dp[0] = 0
100+
for j in xrange(len(andValues)):
101+
new_dp = [INF]*(len(nums)+1)
102+
masks = []
103+
st = SparseTable(dp, min)
104+
for i in xrange(j, len(nums)):
105+
masks.append([nums[i], i])
106+
for x in masks:
107+
x[0] &= nums[i]
108+
masks = [x for k, x in enumerate(masks) if k == 0 or masks[k-1][0] != masks[k][0]]
109+
for k, [mask, left] in enumerate(masks):
110+
right = masks[k+1][1]-1 if k+1 != len(masks) else i
111+
if mask == andValues[j]:
112+
# any j in range(left, right+1) have same and(nums[j:i+1]) = mask
113+
new_dp[i+1] = min(new_dp[i+1], st.query(left, right)+nums[i])
114+
break
115+
dp = new_dp
116+
return dp[-1] if dp[-1] != INF else -1
117+
118+
61119
# Time: O(n * m * logr), r = max(nums)
62120
# Space: O(n * m * logr)
63121
import collections
64122

65123

66124
# memoization
67-
class Solution2(object):
125+
class Solution3(object):
68126
def minimumValueSum(self, nums, andValues):
69127
"""
70128
:type nums: List[int]

0 commit comments

Comments
 (0)