#include "bits/stdc++.h"
using namespace std;

//諸機能
#pragma region MACRO 
#define putans(x)  std::cerr << "[ answer ]: " ; cout << (x) << endl
#define dputans(x) std::cerr << "[ answer ]: "; cout << setprecision(27) << (double)(x) << endl
#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define RREP(i,a,n) for(int i=(int)(n-1); i>= a; i--)
#define rep(i,n) REP(i,0,n)
#define rrep(i,n) RREP(i,0,n)
#define all(a) begin((a)),end((a))
#define mp make_pair
#define exist(container, n) ((container).find((n)) != (container).end())
#define equals(a,b) (fabs((a)-(b)) < EPS)
#ifdef _DEBUG //ファイルからテストデータを読み込む
std::ifstream ifs("data.txt");
#define put ifs >>
#else //ジャッジシステムでいい感じにやる
#define put cin >>
#endif
#pragma endregion
//デバッグなどの支援
#pragma region CODING_SUPPORT
#ifdef _DEBUG
#define dbg(var0) { std::cerr << ( #var0 ) << "=" << ( var0 ) << endl; }
#define dbg2(var0, var1) { std::cerr << ( #var0 ) << "=" << ( var0 ) << ", "; dbg(var1); }
#define dbg3(var0, var1, var2) { std::cerr << ( #var0 ) << "=" << ( var0 ) << ", "; dbg2(var1, var2); }
#define dbgArray(a,n) {std::cerr << (#a) << "=";  rep(i,n){std::cerr <<(a[i])<<",";} cerr<<endl;} 
#else
#define dbg(var0) {}
#define dbg2(var0, var1) {}
#define dbg3(var0, var1, var2) {}
#define dbgArray(a,n) {}
#endif 
#pragma endregion 
//typedef（書き換える、書き足す可能性ある）
#pragma region TYPE_DEF
typedef long long ll;
typedef pair<int, int> pii; typedef pair<string, string> pss; typedef pair<int, string>pis;
typedef vector<string> vs; typedef vector<int> vi;
#pragma endregion
//諸々の定数(書き換える可能性ある)
#pragma region CONST_VAL
#define PI (2*acos(0.0))
#define EPS (1e-10)
#define MOD (ll)(1e9 + 7)
#define INF (ll)(2*1e9)
#pragma endregion

typedef pii range;


//区間に対する演算を高速に求めるためのセグメント木
namespace SegmentTree {
	//コンストラクタ
	//tに参照型（ポインタ系）使ったらどうなるか不明、えぐいバグ出しそう
	//int double とかのnumeric系に絞ったほうがよさげ
	//n 要素数
	//invalid_value 無効な数値　任意のaについてmarge(a,invalidvalue) = a, marge(invalid_value, a) = a　となるような値
	//eval_func_invalid_value(t value) valueが不正な数値化どうか調べる
	//　*marge(t a, t, b) aとbから a∪bを求める関数、自分で様々な計算方法をここで決めるemplate<typename t="">
	template<typename t>
	class SegmentTree {
	public:
		SegmentTree(int n, t invalid_value, bool(*eval_func_invalid_value)( t ), t(*marge_method)( t, t ));
		~SegmentTree();
		void SetElem(int k, t val);
		int GetCount();
		t quary(int a, int b);
		t GetElem(int k);
		//invalid_valueを元に不正な数値かどうか調べる
		bool(*IsInvalidValue)( t value );
		//aとbから a∪bを求める関数、自分で計算方法をここで決める
		t(*Marge)( t a, t b );
	private:
		vector<t>
			mTree;
		int mCount;
		t mInvalidValue;
		void Update(int k, t val);
		t InternalQuary(int a, int b, int k, int l, int r);
	};

	template<typename t>
	SegmentTree<t>
		::SegmentTree(int n, t invalid_value, bool(*eval_func_invalid_value)( t ), t(*marge_method)( t, t )) {
		int bin_n = 1;
		while (bin_n < n) bin_n *= 2;
		mTree.resize(2 * bin_n);
		mInvalidValue = invalid_value;
		mCount = bin_n;
		for (int i = 0; i < 2 * bin_n - 1; i++) {
			mTree[i] = invalid_value;
		}
		IsInvalidValue = eval_func_invalid_value;
		Marge = marge_method;
	}

	template<typename t>
	SegmentTree<t>
		::~SegmentTree() {
	}

	template<typename t>
	void SegmentTree<t>
		::SetElem(int k, t val) {
		Update(k, val);
	}

	template<typename t>
	t SegmentTree<t>
		::GetElem(int k) {
		return mTree[mCount - 1 + k];
	}

	template<typename t>
	int SegmentTree<t>
		::GetCount() {
		return mCount;
	}

	template<typename t>
	void SegmentTree<t>
		::Update(int k, t val) {
		k += mCount - 1;
		mTree[k] = val;
		while (k > 0) {
			k = ( k - 1 ) / 2;
			mTree[k] = Marge(mTree[2 * k + 1], mTree[2 * k + 2]);
		}
	}

	//区間[a,b]の値をO(lon(Count))で求める b < GetCountとすること
	template<typename t>
	t SegmentTree<t>
		::quary(int a, int b) {
		return InternalQuary(a, b + 1, 0, 0, mCount);
	}

	template<typename t>
	t SegmentTree<t>
		::InternalQuary(int a, int b, int k, int l, int r) {
		if (r <= a || b <= l)return mInvalidValue;
		if (a <= l && r <= b)return mTree[k];
		else {
			int vl = InternalQuary(a, b, k * 2 + 1, l, ( l + r ) / 2);
			int vr = InternalQuary(a, b, k * 2 + 2, ( l + r ) / 2, r);
			return Marge(vl, vr);
		}
	}
}


int comp(int a, int b) {
	return min(a, b);
}
bool isValid(int a) {
	return a != INF;
}

int main() {
	int n; put n;
	vi a(n);
	vi index(n);
	rep(i, n) {
		put a[i];
		index[a[i] - 1] = i;
	}
	queue<range> s;
	SegmentTree::SegmentTree<int> rmq(n,INF,isValid,comp);
	rep(i, n) rmq.SetElem(i,a[i]);
	s.push({0,n-1});
	ll ans = 0;
	while (!s.empty()) {
		range r = s.front(); s.pop();
		if (r.first == r.second) {
			ans += a[r.first];

			continue;
		}
		int min = rmq.quary(r.first, r.second);
		int minI = index[min-1];
		ans += (ll)min * (ll)(r.second - minI + 1) * (ll)(minI - r.first + 1);
		dbg2(r.first, r.second);
		dbg2(min-1, index[min-1]);
		dbg(ans);
		dbg(" ");
		if (r.first == minI) {
			s.push({ r.first + 1,r.second });
		}
		else if (minI == r.second) {
			s.push({ r.first, r.second-1 });
		}
		else {
			s.push({ r.first,minI-1 });
			s.push({ minI + 1,r.second });
		}
	}
	putans(ans);
END:
	return 0;
}

//
//vi v;
//vi w; ;
//ll nz1() {
//	return 0;
//}
//
//ll nz2() {
//	ll dp[201][1000*200+1];
//
//}
//
//ll nz3() {
//
//}
//	int n, wkazu; put n >> wkazu;
//	v.resize(200); 
//	w.resize(200);
//	rep(i, n) {
//		put v[i] >> w[i];
//	}

	//int h, w; put h >> w;
	//int map[100][100];
	//int ans[100][100];
	//rep(i, h) {
	//	string s; put s;
	//	rep(j, w) {
	//		map[i][j] = s[j] == '#' ? 1 : 0;
	//	}
	//}
	//int vx[9] = { 1,1,1,0,0,0,-1,-1,-1 };
	//int vy[9] = { 1,0,-1,1,0,-1,1,0,-1 };
	//rep(i, h) {
	//	rep(j, w) {
	//		int flag = 0;
	//		if (i  == 0 || i == h-1)flag++;
	//		if (j  == 0 || j == w-1)flag++;
	//		int match = flag == 0 ? 9 : ( flag == 1 ? 6 : 4 );
	//		int tester = 0;
	//		rep(k, 9) {
	//			if (i + vy[k] < 0 || i + vy[k] >= h) continue;
	//			if (j + vx[k] < 0 || j + vx[k] >= w) continue;
	//			tester += map[i+vy[k]][j+vx[k]];
	//		}
	//		if (tester == match) ans[i][j] = 1;
	//		else ans[i][j] = 0;
	//	}
	//}
	//int test[100][100] = { 0 };
	//rep(i, h) {
	//	rep(j, w) {
	//		if (ans[i][j] == 1) {
	//			rep(k, 9) {
	//				if (i + vy[k] < 0 || i + vy[k] >= h) continue;
	//				if (j + vx[k] < 0 || j + vx[k] >= w) continue;
	//				test[i + vy[k]][j + vx[k]] = 1;
	//			}
	//		}
	//	}
	//}
	//rep(i, h) {
	//	rep(j, w) {
	//		if ( test[i][j] != map[i][j] ) {
	//			cout << "impossible" << endl;
	//			goto END;
	//		}
	//	}
	//}
	//cout << "possible" << endl;
	//rep(i, h) {
	//	rep(j, w) {
	//		cout << ( ans[i][j] == 1 ? "#" : "." );
	//	}
	//	cout << endl;
	//}


//int n, m; put n >> m;
//string s1; put s1;
//string s2; put s2;
//int l1 = s1.size();
//int l2 = s2.size();
//int dp[1001][1001];
//rep(i, l1+1) {
//	dp[i][0] = i;
//}
//rep(i, l2+1) {
//	dp[0][i] = i;
//}
//rep(i, l1) {
//	rep(j, l2) {
//		int cost = (s1[i] == s2[j]) ? 0 : 1;
//		dp[i + 1][j + 1] = min(dp[i][j+1]+1,min(dp[i+1][j]+1,dp[i][j]+cost));
//	}
//}
//cout << dp[l1][l2] << endl;

Measured memory_bytes: 3968