Sum of Subarray Minimums in C++



Suppose we have an array of integers A. We have to find the sum of min(B), where B ranges over every (contiguous) subarray of A. Since the answer may be very large, then return the answer in modulo 10^9 + 7. So if the input is like [3,1,2,4], then the output will be 17, because the subarrays are [3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4], so minimums are [3,1,2,4,1,1,2,1,1,1], and the sum is 17.

To solve this, we will follow these steps −

  • m := 1 x 10^9 + 7

  • Define two methods, add() will take a, b and returns the (a mod m + b mod m) mod m, mul() will take a, b and returns the (a mod m * b mod m) mod m

  • The main method will take the array A, define a stack st, and set n := size of array A

  • Define two arrays left of size n and fill with -1, and another is right of size n, fill with n

  • set ans := 0

  • for i in range 0 to n – 1

    • while st is not empty and A[stack top] >= A[i], delete from st

    • if st is not empty, then set left[i] := top of st

    • insert i into st

  • while st is not empty, then delete st

  • for i in range n – 1 down to 0

    • while st is not empty and A[stack top] >= A[i], delete from st

    • if st is not empty, then set right[i] := top of st

    • insert i into st

  • for i in range 0 to n – 1

    • leftBound := i – left[i] + 1, rightBound := right[i] – 1 – i

    • contri := 1 + leftBound + rightBound + (leftBound * rightBound)

    • ans := add(ans and mul(contri, A[i]))

  • return ans

Example(C++)

Let us see the following implementation to get better understanding −

 Live Demo

#include <bits/stdc++.h> using namespace std; typedef long long int lli; const lli MOD = 1e9 + 7; class Solution { public:    lli add(lli a, lli b){       return (a % MOD + b % MOD) % MOD;    }    lli mul(lli a, lli b){       return (a % MOD * b % MOD) % MOD;    }    int sumSubarrayMins(vector<int>& A) {       stack <int> st;       int n = A.size();       vector <int> left(n, -1);       vector <int> right(n, n);       int ans = 0;       for(int i = 0; i < n; i++){          while(!st.empty() && A[st.top()] >= A[i]){          st.pop();       }       if(!st.empty())left[i] = st.top();          st.push(i);       }       while(!st.empty())st.pop();       for(int i = n - 1; i >= 0; i--){          while(!st.empty() && A[st.top()] > A[i]){             st.pop();          }          if(!st.empty())right[i] = st.top();             st.push(i);       }       for(int i = 0; i < n; i++){          int leftBound = i - (left[i] + 1);          int rightBound = (right[i] - 1) - i;          int contri = 1 + leftBound + rightBound + (leftBound * rightBound);          ans = add(ans, mul(contri, A[i]));       }       return ans;    } }; main(){    vector<int> v = {3,1,2,4};    Solution ob;    cout << (ob.sumSubarrayMins(v)); }

Input

[3,1,2,4]

Output

17
Updated on: 2020-04-30T10:35:55+05:30

229 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements
close