#include <bits/stdc++.h>
template <typename T>
struct SegmentTreeUpdMin {
  int n;
  const T inf = std::numeric_limits<T>::max();
  std::vector<T> node;
  SegmentTreeUpdMin(std::vector<T> v) {
    int sz = v.size();
    n = 1; while(n < sz) n *= 2;
    node.resize(2*n, inf);
    for(int i=0;i<sz;++i) node[i+n-1] = v[i];
    for(int i=n-2;i>=0;--i) node[i] = std::min(node[2*i+1], node[2*i+2]);
  }
  void update(int idx, T val) {
    assert(0 <= idx && idx < n);
    node[idx + n - 1] = val;
    idx = idx + n - 1;
    while(idx > 0) {
      idx = (idx - 1) / 2;
      node[idx] = std::min(node[2*idx + 1], node[2*idx + 2]);
    }
  }
  T query(int a, int b, int k, int l, int r) {
    if(r <= a || b <= l) return inf;
    if(a <= l && r <= b) return node[k];
    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 std::min(vl, vr);
  }
  T query(int a, int b) {
    return query(a, b, 0, 0, n);
  }
};
template <typename T>
class SegmentTreeUpdMax {
    int n;
    const T inf_min = std::numeric_limits<T>::min();
    std::vector<T> node;
public:
    SegmentTreeUpdMax() {}
    SegmentTreeUpdMax(std::vector<T> v) {
        int sz = v.size();
        n = 1; while(n < sz) n *= 2;
        node.resize(2*n, inf_min);
        for(int i=0;i<sz;++i) node[i+n-1] = v[i];
        for(int i=n-2;i>=0;--i) node[i] = std::max(node[2*i+1], node[2*i+2]);
    }
    void update(int idx, T val) {
        assert(0 <= idx && idx < n);
        node[idx + n - 1] = val;
        idx = idx + n - 1;
        while(idx > 0) {
            idx = (idx - 1) / 2;
            node[idx] = std::max(node[2*idx + 1], node[2 * idx + 2]);
        }
    }
    T query(int a, int b, int k, int l, int r) {
        if(r <= a || b <= l) return inf_min;
        if(a <= l && r <= b) return node[k];
        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 std::max(vl, vr);
    }
    T query(int a, int b) {
        return query(a, b, 0, 0, n);
    }
};
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
  if(a < b) {a = b; return true;}
  return false;
}
template <typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
  if(a > b) {a = b; return true;}
  return false;
}
template<typename T1, typename T2>
ostream& operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for(int i=0;i<((int)(v.size()));++i) {
    if(i) os << " ";
    os << v[i];
  }
  return os;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int n; cin >> n;
  vector<P> v(n);
  for(int i=0;i<(n);++i) {
    cin >> v[i].first;
    v[i].second = i;
  }
  sort((v).begin(),(v).end());
  vll vmi(n, INF), vma(n, -INF);
  SegmentTreeUpdMin<ll> stmi(vmi);
  SegmentTreeUpdMax<ll> stma(vma);
  ll ans = 0;
  for(int i=0;i<(n);++i) {
    int now = v[i].first;
    int idx = v[i].second;
    ll l = stma.query(0, idx+1);
    ll r = stmi.query(idx, n);
    if(l == -INF) l = -1;
    if(r == INF) r = n;
    ans += (idx - l) * (r - idx) * now;
    stmi.update(idx, idx);
    stma.update(idx, idx);
  }
  cout << ans << endl;
}


Measured memory_bytes: 14692