給定一個整數數組 A,找到 min(B) 的總和,其中 B 的範圍爲 A 的每個(連續)子數組。
由於答案可能很大,因此返回答案模 10^9 + 7。
示例:
輸入:[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。
提示:
1 <= A <= 30000
1 <= A[i] <= 30000
//翻轉vector
template<typename T>
vector<T> frev(vector<T> v)
{
vector<T> ans;
for(int i=v.size()-1;i>=0;i--)ans.push_back(v[i]);
return ans;
}
//vector乘一個數
template<typename T>
void fcheng(vector<T> &v,int n)
{
for(int i=v.size()-1;i>=0;i--)v[i]*=n;
}
//vector加一個數
template<typename T>
void fjia(vector<T> &v,int n)
{
for(int i=v.size()-1;i>=0;i--)v[i]+=n;
}
//返回vector每個數前面最近的比它小的數的ID,-1 或者 0到size-1
template<typename T>
vector<int> fminlef(vector<T> v)
{
vector<int> ans;
if(v.size()==0)return ans;
stack<T>st;
st.push(0);
ans.push_back(-1);
for(int i=1;i<v.size();i++)
{
while(!st.empty() && v[st.top()]>=v[i])st.pop();
if(st.empty())ans.push_back(-1);
else ans.push_back(st.top());
st.push(i);
}
return ans;
}
//返回vector每個數後面最近的比它小的數的ID,size 或者 0到size-1
template<typename T>
vector<int> fminrig(vector<T> v)
{
vector<int>v1=frev(v),v2=fminlef(v1);
fcheng(v2,-1);
fjia(v2,v.size()-1);
return frev(v2);
}
//返回vector每個數前面最近的比它小或等於的數的ID,-1 或者 0到size-1
template<typename T>
vector<int> fminlef2(vector<T> v)
{
vector<int> ans;
if(v.size()==0)return ans;
stack<T>st;
st.push(0);
ans.push_back(-1);
for(int i=1;i<v.size();i++)
{
while(!st.empty() && v[st.top()]>v[i])st.pop();
if(st.empty())ans.push_back(-1);
else ans.push_back(st.top());
st.push(i);
}
return ans;
}
//返回vector每個數後面最近的比它小或等於的數的ID,size 或者 0到size-1
template<typename T>
vector<int> fminrig2(vector<T> v)
{
vector<int>v1=frev(v),v2=fminlef2(v1);
fcheng(v2,-1);
fjia(v2,v.size()-1);
return frev(v2);
}
class Solution {
public:
int sumSubarrayMins(vector<int>& A) {
vector<int>v1=fminlef(A),v2=fminrig2(A);
int ans=0;
for(int i=0;i<A.size();i++)
{
int m=min(i-v1[i],v2[i]-i);
ans+=(v2[i]-v1[i]-m)*m*A[i],ans%=1000000007;
}
return ans;
}
};