lc907 子陣列的最小值之和

chenfy27發表於2024-03-17

給定陣列arr[n],求所有子陣列中最小值的和,答案對1e9+7取模。
1<=n<=30000; 1<=arr[i]<=30000

考慮每個數作為最小值對應的子陣列有多少個,計算對答案的貢獻,而子陣列的個數可以用單調棧來維護。陣列元素可能相同,為了避免重複計數,用半開半閉區間。

class Solution {
public:
    int sumSubarrayMins(vector<int>& arr) {
        int n = arr.size();
        vector<int> L(n), R(n), s;
        for (int i = 0; i < n; i++) {
            while (!s.empty() && arr[i] < arr[s.back()])
                s.pop_back();
            L[i] = s.empty() ? -1 : s.back();
            s.push_back(i);
        }
        s.clear();
        for (int i = n-1; i >= 0; i--) {
            while (!s.empty() && arr[i] <= arr[s.back()])
                s.pop_back();
            R[i] = s.empty() ? n : s.back();
            s.push_back(i);
        }
        long long ans = 0;
        for (int i = 0; i < n; i++) {
            ans += 1LL * arr[i] * (i-L[i]) * (R[i]-i);
            ans %= 1000000007;
        }
        return ans;
    }
};

相關文章