#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>

using namespace std;

inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}

typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define MP make_pair
#define MT make_tuple
#define EACH(i,c) for(auto i: c)
#define SORT(c) sort((c).begin(),(c).end())

#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()

const double EPS = 1e-10;
const double PI  = acos(-1.0);

#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

template <typename T, typename Compare=less<T> >
class SegmentTree {
 public:
  SegmentTree(int num, T default_value=T())
      : default_(default_value) {
    num_ = 1;
    while (num_ <= num) num_ <<= 1;
    dat_.resize(2 * num_ - 1, default_);
  }

  void Update(int index, T value) {
    index += num_ - 1;
    dat_[index] = value;

    while (index > 0) {
      index = (index - 1) / 2;
      dat_[index] = Compare_(dat_[index * 2 + 1], dat_[index * 2 + 2]);
    }
  }

  // [from, to]
  T Query(int from, int to) {
    return Query_(from, to + 1, 0, 0, num_);
  }

 private:
  vector<T> dat_;
  int num_;
  T default_;

  T Compare_(T x, T y) { return Compare()(x, y) ? x : y; }

  T Query_(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) return default_;
    if (a <= l && r <= b) {
      return dat_[k];
    } else {
      T vl = Query_(a, b, k * 2 + 1, l, (l + r) / 2);
      T vr = Query_(a, b, k * 2 + 2, (l + r) / 2, r);
      return Compare_(vl, vr);
    }
  }
};

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N;
	cin >> N;

	VI A(N);
	SegmentTree<int> st(N, 1e9);
	REP(i, N){
		cin >> A[i];
		st.Update(i, A[i]);
	}

	VI L(N), R(N);
	REP(i, N){
		int l = 0, r = i + 1;
		while(l + 1 < r){
			int mid = (l + r) / 2;
			int m = st.Query(mid, i);
			if(m < A[i]) l = mid;
			else r = mid;
			//cout << i << " " << mid << " " << l << " " << r << " " << m << endl;
		}
		if(st.Query((l + r) / 2, i) < A[i]) l++;
		L[i] = i - (l + r) / 2;

		l = i;
		r = N;
		while(l + 1 < r){
			int mid = (l + r) / 2;
			int m = st.Query(i, mid);
			if(m < A[i]) r = mid;
			else l = mid;
			//cout << i << " " << mid << " " << l << " " << r << " " << m << endl;
		}
		if(st.Query(i, (l + r) / 2) < A[i]) r--;
		R[i] = (l + r) / 2 - i;
	}

//	REP(i, N){
//		FOR(j, i, N){
//			cout << i << " " << j << " " << st.Query(i, j) << endl;;
//		}
//	}

//	EACH(l, L) cout << l << " ";
//	cout << endl;
//	EACH(r, R) cout << r << " ";
//	cout << endl;

	LL ret = 0;
	REP(i, N){
		ret += (LL)A[i] * (L[i] + 1) * (R[i] + 1);
	}

	cout << ret << endl;

	return 0;
}


Measured memory_bytes: 4608