#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>


using namespace std;
using lint = long long;
using P = pair<lint, lint>;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define repn(i, a, b) for(int i = (a); i < (b); ++i)
#define rep_inv(i, n) for (int i = (n); i >= 0; --i)
#define rep_inv1(i, n) for(int i = (n); i >= 1; --i)
#define all(vec) (vec).begin(), (vec).end()
#define cend printf("\n")

constexpr lint Mod = /**/ 1000'000'007LL /*/ 998'244'353LL /**/;
constexpr lint Inf = 4'500'000'000'000'000'007LL; //4.5e18+7
constexpr double Pi = 3.141592653589793;

template<class T> using prique     = priority_queue<T>;
template<class T> using prique_inv = priority_queue<T, vector<T>, greater<T>>;
template<class T> inline T read() {
	T x{}; cin >> x;
	return x;
}
template<class T> inline bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template<class T> inline bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template<class T> inline istream& operator>>(istream& is, vector<T>& v) { for (auto& e : v) is >> e; return is; }
template<class T> inline ostream& operator<<(ostream& os, const vector<T>& v) {
	os << "{ ";
	for (size_t i = 0, n = v.size(); const auto& e : v) {
		if (i + 1 < n) os << e << ", ";
		else os << e << " }";
		++i;
	}
	return os;
}
template<class T, class U> inline istream& operator>>(istream& is, pair<T, U>& rhs) { return is >> rhs.first >> rhs.second; }
template<class T, class U> inline ostream& operator<<(ostream& os, const pair<T, U>& rhs) { return os << "{" << rhs.first << ", " << rhs.second << "}"; }
template<class T, class U> inline void print(const T& a, const U& b, bool f) {
	if (f) cout << a << "\n";
	else cout << b << "\n";
}
template<class InputIterator> void arrin(InputIterator first, InputIterator last) { for (; first != last; ++first) cin >> (*first); }
template<class InputIterator> void arrout(InputIterator first, InputIterator last) {
	for (; first != last; ++first) {
		cout << (*first) << ((first + 1) != last ? " " : "\n");
	}
}
template<class Head, class ...Tail> tuple<Head, Tail...> reads() {
	Head head; cin >> head;

	const tuple<Head>& tup = std::make_tuple(head);

	if constexpr (sizeof...(Tail) == 0) return tup;
	else return std::tuple_cat(tup, reads<Tail...>());
}

bool pri(lint x) { 
	for (lint i = 2; i * i <= x; ++i) {
		if (x % i == 0) return false;
	}
	return 1 < x; 
}

lint fact[3'000'000];
void fact_init(lint n, lint m = Mod) {
	if (3'000'000 <= n) return;
	fact[0] = fact[1] = 1;
	for (lint i = 2; i <= n; ++i) {
		fact[i] = i * fact[i - 1] % m;
	}
}

lint modpow(lint x, lint n, lint m = Mod) {
	lint res = 1;
	while (n > 0) {
		if (n & 1) res = res * x % m;
		x = x * x % m;
		n >>= 1;
	}
	return res;
}

lint intpow(lint x, lint n) {
	lint res = 1;
	while (n > 0) {
		if (n & 1) res *= x;
		x *= x;
		n >>= 1;
	}
	return res;
}

lint comb(lint n, lint r, lint m = Mod) {
	if (r == 0 || r == n) return 1;
	lint res = fact[n] * modpow(fact[n - r], m - 2, m) % m * modpow(fact[r], m - 2, m) % m;
	return res < 0 ? res + m : res;
}

map<lint, lint> factring(lint n) {
	map<lint, lint> res;
	for (lint i = 2; i * i <= n; ++i) {
		while (n % i == 0) {
			n /= i;
			++res[i];
		}
	}
	if (n != 1) ++res[n];
	return res;
}

template<class T>
class segment_tree {
private:

	int size;
	vector<T>dat;
	T identity;
	function<T(T, T)>func;

	T query_sub(int a, int b, int k, int l, int r) const {
		if (r <= a || b <= l) return identity;
		if (a <= l && r <= b) return dat[k];
		const T& vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
		const T& vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
		return func(vl, vr);
	}

public:

	segment_tree(int size_, const T& identity, const function<T(T, T)>& func)
		:identity(identity), func(func)
	{
		int x = 1;
		while (size_ > x) x <<= 1;
		size = x;
		dat.resize(2 * size - 1, identity);
	}

	void update(int i, const T& x) {
		i += size - 1;
		dat[i] = x;
		while (i > 0) {
			i = (i - 1) / 2;
			dat[i] = func(dat[i * 2 + 1], dat[i * 2 + 2]);
		}
	}

	// [a, b)
	T query(int a, int b) const { return query_sub(a, b, 0, 0, size); }

	const T& operator[](size_t index) const { return dat[index + size - 1]; }
	T& operator[](size_t index) { return dat[index + size - 1]; }
};

int n;
lint sum;
int main() {
	scanf("%d", &n);

	segment_tree<int>seg(n, 10000000, [](int x, int y) {return min(x, y); });

	rep(i, n) {
		int a;
		scanf("%d", &a);
		seg.update(i, a);
	}

	rep(i, n) {
		const int a = seg[i];

		lint cnt1, cnt2;

		int l = -1, r = i;
		while (abs(r - l) > 1) {
			int mid = l + (r - l) / 2;
			if (seg.query(mid, i + 1) == a) r = mid;
			else l = mid;
		}

		cnt1 = i - r + 1;

		l = i, r = n;
		while (abs(r - l) > 1) {
			int mid = l + (r - l) / 2;
			if (seg.query(i, mid + 1) == a) l = mid;
			else r = mid;
		}

		cnt2 = l - i + 1;

		sum += cnt1 * cnt2 * a;
	}

	cout << sum << endl;
}

Measured memory_bytes: 5392