publicintsumSubarrayMins(int[] arr){int MOD =(int)1e9+7;int n = arr.length;long sum =0;Stack<Integer> stk =newStack<>();int j, k;for(int i =0; i <= n; i++){while(!stk.isEmpty()&& arr[stk.peek()]>(i == n ?Integer.MIN_VALUE : arr[i])){
j = stk.pop();
k = stk.isEmpty()?-1: stk.peek();
sum +=(long) arr[j]*(i - j)*(j - k);}
stk.push(i);}return(int)(sum % MOD);}
另外
publicintsumSubarrayMins(int[] arr){int MOD =(int)1e9+7;//存的是当前元素的下标索引Deque<Integer> stk =newArrayDeque<>();int[]A=newint[arr.length +1];//最后一个元素作为哨兵for(int i =0; i < arr.length; i++)A[i]= arr[i];// A[A.length-1] = 0;intN=A.length;long res =0;for(int i =0; i <N; i++){//遍历到的元素比栈顶的元素(遍历到的元素最近的一个元素)要小while(!stk.isEmpty()&&A[i]<=A[stk.peek()]){//设置弹出的元素是当前元素int index = stk.pop();//前一个元素int prev =-1;if(!stk.isEmpty()) prev = stk.peek();int m = index - prev -1;//int n = i - index -1;
res +=(long)(A[index])*(m +1)*(n +1)% MOD;
res %= MOD;}
stk.push(i);}return(int) res;}
方法2:计算左右的贡献值
publicintsumSubarrayMins(int[] nums){int MOD =(int)1e9+7;int n = nums.length;Deque<Integer> stk =newArrayDeque<>();int[] left =newint[n], right =newint[n];//找到左侧第一个比nums[i]小的下标,维护一个单调递增栈for(int i =0; i < n; i++){//栈顶元素不小于(即大于等于)当前元素,此时有递减的趋势,弹出栈顶元素while(!stk.isEmpty()&& nums[stk.peek()]>= nums[i]){
stk.pop();}
left[i]= stk.isEmpty()?-1: stk.peek();
stk.push(i);}
stk.clear();//栈顶元素大于(此处没有等于,此处与上一处只能一处有等于,防止重复计算)当前元素,此时有递减的趋势,弹出栈顶元素for(int i = n -1; i >=0;--i){while(!stk.isEmpty()&& nums[stk.peek()]> nums[i]){
stk.pop();}
right[i]= stk.isEmpty()? n : stk.peek();
stk.push(i);}long res =0;for(int i =0; i < n; i++){
res +=1L*(i - left[i])*(right[i]- i)* nums[i];
res %= MOD;}return(int) res;}
方法3
int MOD =(int)1e9+7;publicintsumSubarrayMins(int[]A){Stack<Pair> stack =newStack<>();int res =0, t =0;for(int i =0; i <A.length; i++){int count =1;while(!stack.empty()&& stack.peek().val >=A[i]){Pair pair = stack.pop();
count += pair.count;
t -= pair.val * pair.count;}
stack.push(newPair(A[i], count));
t +=A[i]* count;
res += t;
res %= MOD;}return res;}classPair{publicint val;publicint count;publicPair(int val,int count){this.val = val;this.count = count;}}