题意:
解法:
每个子区间的贡献= 子区间ma- 子区间mi.
考虑分开计算, 计算所有子区间的ma的和, 减去所有子区间的mi的和.
单调栈计算出每个数作为ma的最大左右扩展距离lma[ i] 和rma[ i] ,
那么a[ i] 作为ma的总贡献就是( i- lma[ i] + 1 ) * ( rma[ i] - i+ 1 ) * a[ i] .
mi同理.
code:
# include <bits/stdc++.h>
# define int long long
using namespace std;
const int maxm= 2e6 + 5 ;
int lmi[ maxm] , rmi[ maxm] ;
int lma[ maxm] , rma[ maxm] ;
stack< int > s;
int a[ maxm] ;
int n;
void solve ( ) {
cin>> n;
for ( int i= 1 ; i<= n; i++ ) cin>> a[ i] ;
a[ 0 ] = a[ n+ 1 ] = 1e9 ;
while ( s. size ( ) ) s. pop ( ) ;
for ( int i= 1 ; i<= n+ 1 ; i++ ) {
while ( s. size ( ) && a[ s. top ( ) ] < a[ i] ) {
rma[ s. top ( ) ] = i- 1 ; s. pop ( ) ;
}
s. push ( i) ;
}
while ( s. size ( ) ) s. pop ( ) ;
for ( int i= n; i>= 0 ; i-- ) {
while ( s. size ( ) && a[ s. top ( ) ] <= a[ i] ) {
lma[ s. top ( ) ] = i+ 1 ; s. pop ( ) ;
}
s. push ( i) ;
}
a[ 0 ] = a[ n+ 1 ] = - 1 ;
while ( s. size ( ) ) s. pop ( ) ;
for ( int i= 1 ; i<= n+ 1 ; i++ ) {
while ( s. size ( ) && a[ s. top ( ) ] > a[ i] ) {
rmi[ s. top ( ) ] = i- 1 ; s. pop ( ) ;
}
s. push ( i) ;
}
while ( s. size ( ) ) s. pop ( ) ;
for ( int i= n; i>= 0 ; i-- ) {
while ( s. size ( ) && a[ s. top ( ) ] >= a[ i] ) {
lmi[ s. top ( ) ] = i+ 1 ; s. pop ( ) ;
}
s. push ( i) ;
}
int ans= 0 ;
for ( int i= 1 ; i<= n; i++ ) {
ans+= ( i- lma[ i] + 1 ) * ( rma[ i] - i+ 1 ) * a[ i] ;
ans-= ( i- lmi[ i] + 1 ) * ( rmi[ i] - i+ 1 ) * a[ i] ;
}
cout<< ans<< endl;
}
signed main ( ) {
ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ;
solve ( ) ;
return 0 ;
}