#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const ll HMOD = (ll)1e9 + 7;
const ll LMOD = 998244353;
const ll HINF = (ll)1e18;
const ll LINF = (ll)1e9;
const long double PI = 3.1415926535897932384626433;
const long double EPS = 1e-10;
class Integer {
 public:
  ll gcd(ll a, ll b) {
    if (a == 0 || b == 0) return 0;
    if (a < b) swap(a, b);
    while (b != 0) {
      a = a % b;
      swap(a, b);
    }
    return a;
  }
  ll lcm(ll a, ll b) {
    if (a == 0 || b == 0) return 0;
    return a / gcd(a, b) * b;
  }
  set<ll> divisor(ll N) {
    set<ll> st;
    for (ll i = 1; i * i <= N; i++) {
      if (N % i == 0) {
        st.insert(i);
        st.insert(N / i);
      }
    }
    return st;
  }
  vector<ll> prime_factorization(ll N) {
    vector<ll> v;
    ll M = N;
    for (ll i = 2; i * i <= N; i++) {
      if (M % i == 0) v.push_back(i);
      while (M % i == 0) M /= i;
    }
    if (M != 1) v.push_back(M);
    return v;
  }
  int bitcount(ll N, int K) {
    int cnt = 0;
    for (int i = 0; i < K; i++)
      if (N & (1 << i)) cnt++;
    return cnt;
  }
  ll digitsum(ll N, int K) {
    ll sum = 0;
    for (; N > 0; N /= K) sum += N % K;
    return sum;
  }
};
class Geometry {
 public:
  double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  }
  bool intersection_judgment(double ax, double ay, double bx, double by,
                             double cx, double cy, double dx, double dy) {
    double ta = (cx - dx) * (ay - cy) + (cy - dy) * (cx - ax);
    double tb = (cx - dx) * (by - cy) + (cy - dy) * (cx - bx);
    double tc = (ax - bx) * (cy - ay) + (ay - by) * (ax - cx);
    double td = (ax - bx) * (dy - ay) + (ay - by) * (ax - dx);
    return tc * td < 0 && ta * tb < 0;
  }
};
class Eratosthenes {
 public:
  vector<bool> primary(int N) {
    vector<bool> primary(N + 1, true);
    primary[0] = false;
    if (N == 0) return primary;
    primary[1] = false;
    for (int i = 1; i * i <= N; i++)
      if (primary[i])
        for (int j = 2 * i; j <= N; j += i) primary[j] = false;
    return primary;
  }
};
class Combination_Mod {
 public:
  vector<ll> factorial;
  void set(ll N, ll quotient) {
    factorial.resize(N + 1, 1);
    for (ll i = 1; i <= N; i++) {
      factorial[i] *= factorial[i - 1] * i;
      factorial[i] %= quotient;
    }
    return;
  }
  ll rsm(ll x, ll n, ll quotient) {
    ll y = 1;
    while (n > 0) {
      if (n & 1) {
        y *= x;
        y %= quotient;
      }
      x *= x;
      x %= quotient;
      n >>= 1;
    }
    return y;
  }
  ll nCk(ll n, ll k, ll quotient) {
    if (n < k || n <= 0 || k <= 0) return 0;
    ll nCk = (factorial[n] % quotient);
    nCk *= rsm(factorial[k], quotient - 2, quotient);
    nCk %= quotient;
    nCk *= rsm(factorial[n - k], quotient - 2, quotient);
    return (nCk % quotient);
  }
};
class Combination {
 public:
  vector<vector<ll>> nCk;
  vector<vector<double>> nCkP;
  void set(int N) {
    nCk.resize(N + 1);
    for (int i = 0; i < int(N + 1); i++) nCk[i].resize(N + 1, 0);
    nCk[0][0] = 1;
    for (int n = 1; n <= N; n++) {
      for (int k = 0; k <= n; k++) {
        if (k == 0)
          nCk[n][k] = nCk[n - 1][k];
        else
          nCk[n][k] = nCk[n - 1][k - 1] + nCk[n - 1][k];
      }
    }
  }
  void setP(int N) {
    nCkP.resize(N + 1);
    for (int i = 0; i < int(N + 1); i++) nCkP[i].resize(N + 1, 0.);
    nCkP[0][0] = 1;
    for (int n = 1; n <= N; n++) {
      for (int k = 0; k <= n; k++) {
        if (k == 0)
          nCkP[n][k] = nCkP[n - 1][k] / 2.;
        else
          nCkP[n][k] = (nCkP[n - 1][k - 1] + nCkP[n - 1][k]) / 2.;
      }
    }
  }
};
class Union_Find {
 public:
  vector<int> node;
  void set(int n) {
    node.resize(n);
    for (int i = 0; i < int(n); i++) node[i] = i;
  }
  int root(int n) {
    if (node[n] == n)
      return n;
    else
      return node[n] = root(node[n]);
  }
  void unite(int n, int m) {
    if (n > m) swap(n, m);
    n = root(n);
    m = root(m);
    if (n == m)
      return;
    else
      node[m] = n;
  }
};
class Dijkstra {
 public:
  vector<vector<pair<int, int>>> edge;
  vector<vector<int>> dist;
  void set(int N, int inf) {
    edge.resize(N);
    dist.resize(N);
    for (int i = 0; i < int(N); i++) dist[i].resize(N);
    for (int i = 0; i < int(N); i++)
      for (int j = 0; j < int(N); j++) dist[i][j] = inf;
  }
  void make_edge(int from, int to, int cost) {
    edge[from].push_back({to, cost});
  }
  void dijkstra(int start) {
    priority_queue<pair<int, int>, vector<pair<int, int>>,
                   greater<pair<int, int>>>
        pq;
    dist[start][start] = 0;
    pq.push({0, start});
    while (!pq.empty()) {
      int from = pq.top().second;
      pq.pop();
      for (int i = 0; i < int(edge[from].size()); i++) {
        int to = edge[from][i].first;
        if (dist[start][to] > dist[start][from] + edge[from][i].second) {
          dist[start][to] = dist[start][from] + edge[from][i].second;
          pq.push({dist[start][from] + edge[from][i].second, to});
        }
      }
    }
  }
};
class Bellman_Ford {
 public:
  struct edge {
    int from, to, cost;
  };
  int N;
  vector<int> node;
  vector<edge> graph;
  void set(int node_, int inf) {
    N = node_;
    node.resize(node_);
  }
  void make_edge(int from, int to, int cost) {
    graph.push_back({from, to, cost});
  }
  void bellman_ford(int start, int inf) {
    for (int i = 0; i < int(N); i++) node[i] = inf;
    node[start] = 0;
    for (int i = 0; i < int(N - 1); i++)
      for (int j = 0; j < int(graph.size()); j++)
        if (node[graph[j].to] > node[graph[j].from] + graph[j].cost)
          node[graph[j].to] = node[graph[j].from] + graph[j].cost;
  }
};
class Ford_Fulkerson {
 public:
  struct edge {
    int to, cap, rev;
  };
  int node, start, goal;
  vector<vector<edge>> graph;
  vector<bool> visit;
  void set(int node_, int start_, int goal_) {
    node = node_;
    start = start_;
    goal = goal_;
    graph.resize(node);
    visit.resize(node);
  }
  void make_edge(int from, int to, int cap) {
    graph[from].push_back({to, cap, (int)graph[to].size()});
    graph[to].push_back({from, 0, (int)graph[from].size() - 1});
  }
  int dfs(int from, int flow) {
    if (from == goal) return flow;
    visit[from] = false;
    for (int i = 0; i < int(graph[from].size()); i++) {
      if (visit[graph[from][i].to] && (graph[from][i].cap > 0)) {
        int dflow = dfs(graph[from][i].to, min(flow, graph[from][i].cap));
        if (dflow > 0) {
          graph[from][i].cap -= dflow;
          graph[graph[from][i].to][graph[from][i].rev].cap += dflow;
          return dflow;
        }
      }
    }
    return 0;
  }
  int maxflow(void) {
    int maxflow = 0;
    while (1) {
      for (int i = 0; i < int(graph.size()); i++) visit[i] = true;
      int flow = dfs(start, 1);
      if (flow == 0) return maxflow;
      maxflow += flow;
    }
  }
};
class Longest_Increasing_Subsequence {
 public:
  int N;
  vector<int> dp, ar;
  void set(int N_) {
    N = N_;
    dp.resize(N, LINF);
    ar.resize(N);
  }
  int make(void) {
    for (int i = 0; i < int(N); i++)
      *lower_bound((dp).begin(), (dp).end(), ar[i]) = ar[i];
    return distance(dp.begin(), lower_bound((dp).begin(), (dp).end(), LINF));
  }
};
class Least_Common_Ancestor {
 public:
  int node;
  int MAXLOG2;
  vector<vector<int>> edge;
  vector<int> depth;
  vector<vector<int>> parent;
  void set(int node_, int MAXLOG2_) {
    node = node_;
    MAXLOG2 = MAXLOG2_;
    edge.resize(node);
    depth.resize(node);
    parent.resize(node);
    for (int i = 0; i < int(node); i++) parent[i].resize(MAXLOG2);
  }
  void dfs(int root, int root_from) {
    depth[root] = 0;
    parent[root][0] = root_from;
    stack<pair<int, int>> st;
    st.push({root, root_from});
    while (!st.empty()) {
      int from = st.top().first;
      int from_from = st.top().second;
      st.pop();
      for (int i = 0; i < int(edge[from].size()); i++) {
        int to = edge[from][i];
        if (to != from_from) {
          depth[to] = depth[from] + 1;
          parent[to][0] = from;
          st.push({to, from});
        }
      }
    }
    return;
  }
  void initialize(int N) {
    for (int k = 0; k < int(MAXLOG2 - 1); k++) {
      for (int i = 0; i < int(N); i++) {
        if (parent[i][k] < 0)
          parent[i][k + 1] = -1;
        else
          parent[i][k + 1] = parent[parent[i][k]][k];
      }
    }
    return;
  }
  int get(int a, int b) {
    if (depth[a] > depth[b]) swap(a, b);
    for (int k = 0; k < int(MAXLOG2 - 1); k++)
      if (((depth[b] - depth[a]) >> k) & 1) b = parent[b][k];
    if (a == b) return a;
    for (int k = int(MAXLOG2 - 1); k >= 0; k--) {
      if (parent[a][k] != parent[b][k]) {
        a = parent[a][k];
        b = parent[b][k];
      }
    }
    return parent[a][0];
  }
};
class Directed_Acyclic_Graph {
 public:
  int N;
  Dijkstra dijkstra;
  struct edge {
    int dest, cost;
    bool need;
  };
  vector<vector<edge>> output;
  vector<int> input;
  vector<int> topological_order;
  void set(int N_, int inf) {
    N = N_;
    dijkstra.set(N, inf);
    output.resize(N);
    input.resize(N, 0);
  }
  void make_edge(int from, int to, int cost) {
    dijkstra.make_edge(from, to, cost);
    output[from].push_back({to, cost, true});
  }
  void make_dag(int start) {
    dijkstra.dijkstra(start);
    for (int i = 0; i < int(N); i++) {
      for (int j = 0; j < int(output[i].size()); j++) {
        int from = i;
        edge &e = output[i][j];
        if (dijkstra.dist[start][e.dest] - dijkstra.dist[start][from] != e.cost)
          e.need = false;
      }
    }
  }
  bool topological_sort(int start) {
    for (int i = 0; i < int(N); i++)
      for (int j = 0; j < int(output[i].size()); j++)
        if (output[i][j].need) input[output[i][j].dest]++;
    stack<int> st;
    st.push(start);
    while (!st.empty()) {
      int from = st.top();
      st.pop();
      topological_order.push_back(from);
      for (int i = 0; i < int(output[from].size()); i++) {
        edge &e = output[from][i];
        if (e.need) {
          input[e.dest]--;
          if (input[e.dest] == 0) st.push(e.dest);
        }
      }
    }
    bool valid = true;
    for (int i = 0; i < int(N); i++)
      if (input[i] > 0) valid = false;
    return valid;
  }
};
class Binary_Indexed_Tree {
 public:
  int N;
  ll ini;
  vector<ll> bit;
  void set(int N_, ll ini_) {
    N = N_;
    ini = ini_;
    bit.resize(N + 1);
    for (int i = 0; i <= N; i++) bit[i] = ini;
  }
  void add(int i, ll w) {
    for (int j = i; j <= N; j += j & -j) bit[j] += w;
  }
  ll sum(int i) {
    ll ret = ini;
    for (int j = i; j >= 1; j -= j & -j) ret += bit[j];
    return ret;
  }
  void inc(int i, ll w) {
    for (int j = i; j <= N; j += j & -j) bit[j] = (bit[j] > w) ? bit[j] : w;
  }
  ll max(int i) {
    ll ret = ini;
    for (int j = i; j >= 1; j -= j & -j) ret = (ret > bit[j]) ? ret : bit[j];
    return ret;
  }
  void dec(int i, ll w) {
    for (int j = i; j <= N; j += j & -j) bit[j] = (bit[j] < w) ? bit[j] : w;
  }
  ll min(int i) {
    ll ret = ini;
    for (int j = i; j >= 1; j -= j & -j) ret = (ret < bit[j]) ? ret : bit[j];
    return ret;
  }
};
void YN(bool flag) { cout << ((flag) ? "YES" : "NO") << endl; }
void Yn(bool flag) { cout << ((flag) ? "Yes" : "No") << endl; }
void yn(bool flag) { cout << ((flag) ? "yes" : "no") << endl; }
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ll N;
  cin >> N;
  vector<ll> a(N + 1);
  for (int i = 0; i < int(N); i++) {
    ll aa;
    cin >> aa;
    a[aa] = i + 1;
  }
  ll sum = 0;
  set<ll> st = {0, N + 1};
  for (int i = int(1); i < int(N + 1); i++) {
    auto itr = st.lower_bound(a[i]);
    ll r = *itr - a[i];
    itr--;
    ll l = -*itr + a[i];
    sum += r * l * i;
    st.insert(a[i]);
  }
  cout << sum << endl;
  return 0;
}
