# 907. 子数组的最小值之和

### Link

{% embed url="<https://leetcode.cn/problems/sum-of-subarray-minimums/>" %}

### Problem

给定一个整数数组 arr，找到 min(b) 的总和，其中 b 的范围为 arr 的每个（连续）子数组。

由于答案可能很大，因此 返回答案模 10^9 + 7 。

示例 1：

{% code overflow="wrap" %}

```
输入：arr = [3,1,2,4]
输出：17
解释：
子数组为 [3]，[1]，[2]，[4]，[3,1]，[1,2]，[2,4]，[3,1,2]，[1,2,4]，[3,1,2,4]。 
最小值为 3，1，2，4，1，1，2，1，1，1，和为 17。
```

{% endcode %}

示例2：

{% code overflow="wrap" %}

```
输入：arr = [11,81,94,43,3]
输出：444
```

{% endcode %}

提示：

* `1 <= arr.length <= 3 * 104`
* `1 <= arr[i] <= 3 * 104`

### Solution

{% tabs %}
{% tab title="C++" %}

```cpp
class Solution {
public:
    int sumSubarrayMins(vector<int>& arr) {
        int n = arr.size();
        vector<int> monoStack;
        vector<int> left(n), right(n);
        for (int i = 0; i < n; i++ ) {
            while(!monoStack.empty() && arr[i] <= arr[monoStack.back()]){
                monoStack.pop_back();
            }
            left[i] = i - (monoStack.empty()? -1 : monoStack.back());
            monoStack.emplace_back(i);
        }
        monoStack.clear();
        for (int i = n -1; i >= 0; i--) {
            while(!monoStack.empty() && arr[i] < arr[monoStack.back()]){
                monoStack.pop_back();
            }
            right[i] = (monoStack.empty()? n : monoStack.back()) - i; 
            monoStack.emplace_back(i);
        }
        long long ans = 0;
        long long MOD = 1e9+7; 
        for (int i =0; i < n; i++ ){
            ans += (long long) left[i] * right[i] * arr[i];
            ans %= MOD;
        }
        return ans;
    }
};
```

{% endtab %}

{% tab title="Go" %}

```go
func sumSubarrayMins(arr []int) int {
    n := len(arr)
    monoStack := []int{}
    left, right := make([]int, n), make([]int, n)
    for i := 0; i < n; i++ {
        for len(monoStack) > 0 && arr[i] <= arr[monoStack[len(monoStack)-1]] {
            monoStack = monoStack[:len(monoStack)-1]
        }
        if len(monoStack) > 0 {
            left[i] = i - monoStack[len(monoStack)-1]
        }else {
            left[i] = i + 1
        }
        monoStack = append(monoStack, i)
    }
    monoStack = []int{}
    for i := n-1; i >= 0; i-- {
        for len(monoStack) > 0 && arr[i] < arr[monoStack[len(monoStack)-1]] {
            monoStack = monoStack[:len(monoStack)-1]
        }
        if len(monoStack) > 0 {
            right[i] = monoStack[len(monoStack)-1] - i
        }else {
            right[i] = n - i
        }
        monoStack = append(monoStack, i)
    }

    ans := 0
    for i := range left {
        ans += left[i] * right[i] * arr[i]
        ans %= 1e9 + 7
    }
    return ans
}
```

{% endtab %}
{% endtabs %}
