Given an array of integers arr, find the sum of min(b), where b ranges over every (contiguous) subarray of arr. Since the answer may be large, return the answer modulo 109 + 7.

solution

If we figure out how far we can extend in the left and right for each number at index while maintaining that arr[i] is the minimum, we can then enumerate all the possible subarrays based on the number of places to place the “[” or “]” on either side.

To find these bounds, we essentially just want to find the next and previous smaller element, for each element in the array. We do this using a monotonic-stack.

def sumSubarrayMins(self, arr: List[int]) -> int:
	n = len(arr)
	bounds = [[-1, n] for i in range(len(arr))]
	stack = []
	  
	for i in range(n):
		while stack and arr[stack[-1]] > arr[i]:
			# i is popped's NSE
			popped_idx = stack.pop()
			bounds[popped_idx][1] = i
	  
		# stack[-1] is i's PSE
		if stack:
			bounds[i][0] = stack[-1]
		stack.append(i)
	  
	ans = 0
	for i, (lb, rb) in enumerate(bounds):
		lmult = i-lb
		rmult = rb-i
		ans += lmult * rmult * arr[i]
	  
	return ans % (10**9+7)