We need to consider every contiguous subarray of arr, find the minimum element in each, and sum all those minimums. Enumerating all subarrays involves O(n^2) subarrays, and finding the minimum of each from scratch adds another O(n) factor, for O(n^3) overall. That is too slow.
A better perspective is to flip the question. Instead of asking "what is the minimum of each subarray?", ask "for each element, how many subarrays is it the minimum of?" Multiply each element by that count and sum the products. This turns a subarray enumeration problem into a contribution counting problem, which monotonic stacks solve in linear time.
1 <= arr.length <= 3 * 10^4 -- With n up to 30,000, an O(n^2) solution does roughly 450 million operations. That is borderline within typical time limits, so a linear solution is the safer target.1 <= arr[i] <= 3 * 10^4 -- All values are positive integers, with no zeros or negatives.10^9 + 7 -- The unmodded sum can exceed a 64-bit integer (up to about 3 10^4 values times 4.5 10^8 subarrays), so reduce modulo 10^9 + 7 as you accumulate, and use a 64-bit type for the products.Enumerate every subarray, track the running minimum as we extend, and add it to the sum. For each starting index i, extend j from i to n-1, updating the minimum at each step. Carrying the minimum forward avoids recomputing it from scratch, giving O(n^2) instead of O(n^3).
result = 0 and set MOD = 10^9 + 7.i from 0 to n-1:currentMin = arr[i].j from i to n-1:currentMin = min(currentMin, arr[j]).currentMin to result (modulo MOD).result.Loading animation...
This rediscovers each element's contribution independently for every starting index. The next approach computes how many subarrays each element is the minimum of without enumerating them.
Instead of iterating over subarrays and finding their minimums, iterate over elements and count how many subarrays each one is the minimum of. The answer is then the sum of arr[i] * count[i] over all i.
The reach of arr[i] as a minimum is bounded by the nearest smaller element on each side. If the nearest smaller element to the left of i is at index left and the nearest smaller element to the right is at index right, then arr[i] is the minimum of every subarray that starts anywhere in (left, i] and ends anywhere in [i, right). The count of such subarrays is (i - left) * (right - i): the number of valid left endpoints times the number of valid right endpoints.
A monotonic stack finds the previous-smaller and next-smaller boundaries for every index in O(n) total.
Duplicates need care. If two equal elements both treated their boundary as "strictly smaller" on both sides, a subarray whose minimum appears twice would be counted twice. The fix is asymmetric comparisons: take the previous strictly smaller element on the left and the next smaller-or-equal element on the right. Each subarray's minimum is then attributed to exactly one index.
When arr[i] is processed, every index still on the stack holds a value smaller than arr[i] (everything larger or equal was popped), so the top of the stack is the nearest smaller boundary.
For the duplicate case, suppose two equal values sit at positions p and q with p < q. The subarray spanning [p..q] has minimum value equal to both. Its right boundary for p stops at q (the right side stops at the next smaller-or-equal element), so p's reach does not include q. The left boundary for q is the previous strictly smaller element, which lies before p, so q's reach does include p. The subarray is attributed to q alone.
prevLess[i] holds the index of the previous strictly smaller element (or -1 if none exists), and nextLess[i] holds the index of the next smaller-or-equal element (or n if none exists).prevLess[]:arr[i].prevLess[i] = -1. Otherwise, prevLess[i] = stack.peek().i onto the stack.nextLess[]:arr[i].nextLess[i] = n. Otherwise, nextLess[i] = stack.peek().i onto the stack.i, the endpoint counts are left = i - prevLess[i] and right = nextLess[i] - i; sum arr[i] * left * right over all i, modulo 10^9 + 7.Loading animation...
This approach uses three passes and two auxiliary arrays. The next approach folds the boundary lookup and the summation into a single left-to-right pass with a DP recurrence.
A single left-to-right pass can do the work by combining the monotonic stack with a running accumulator. Define dp[i] as the sum of minimums of all subarrays ending at index i. The final answer is dp[0] + dp[1] + ... + dp[n-1].
To compute dp[i], find the previous strictly smaller element at index j (or j = -1 if none exists). Every subarray ending at i that starts at positions j+1 through i has arr[i] as its minimum, since arr[i] is smaller than every element after j up to i. There are i - j such subarrays, contributing arr[i] * (i - j). Every subarray that starts at or before j has its minimum to the left of i, with the same value it had for a subarray ending at j, which is exactly dp[j]. So:
dp[i] = dp[j] + arr[i] * (i - j), with dp[j] dropped when j = -1.
The recurrence relies on a fact about dp[j]: appending arr[i] to any subarray ending at j leaves the minimum of that subarray unchanged when its start is at or before j, because every value between j and i is at least arr[i] and arr[i] is at least arr[j] (j is the previous strictly smaller index). So the minimums of those subarrays carry over unchanged, and their sum is dp[j]. Each index is pushed and popped at most once, so the whole pass is O(n).
dp where dp[i] represents the sum of minimums of all subarrays ending at index i.i from 0 to n-1:arr[stack.top()] >= arr[i].dp[i] = arr[i] * (i + 1) (arr[i] is the minimum of all subarrays ending at i).j = stack.top(). Then dp[i] = dp[j] + arr[i] * (i - j).i onto the stack.dp[i] to the running result.result % MOD.Loading animation...