# Original solution
#!/usr/bin/env python3
import sys
import random

class Node(object):
    __slots__ = ['value', 'cnt', 'pri', 'lch', 'rch']
    def __init__(self, value):
        self.value = value
        self.cnt = 1
        self.pri = random.randint(1, 1 << 64)
        self.lch = None
        self.rch = None

    def __iter__(self):
        if self.lch is not None:
            for x in self.lch.__iter__():
                yield x
        yield self.value
        if self.rch is not None:
            for x in self.rch.__iter__():
                yield x
    
    def __repr__(self):
        return '{}'.format(self.value)

class Treap(object):
    def __init__(self):
        self.root = None

    def __iter__(self):
        if self.root is None:
            pass
        else:
            for v in self.root:
                yield v
    
    def __repr__(self):
        return "[{}]".format(", ".join(map(str, self)))

    def count(self, node):
        if node is None:
            return 0
        return node.cnt

    def total(self, node):
        if node is None:
            return 0
        return node.ttl

    def update(self, node):
        node.cnt = self.count(node.lch) + self.count(node.rch) + 1

    def merge(self, l, r):
        if l is None:
            return r
        
        if r is None:
            return l
        
        if l.pri  > r.pri:
            l.rch = self.merge(l.rch, r)
            self.update(l)
            return l
        else:
            r.lch = self.merge(l, r.lch)
            self.update(r)
            return r

    def split(self, node, k):
        # print("split:", node, k)
        if node is None:
            return (None, None)
        
        if k <= self.count(node.lch):
            s = self.split(node.lch, k)
            node.lch = s[1]
            self.update(node)
            return (s[0], node)
        else:
            s = self.split(node.rch, k - self.count(node.lch) - 1)
            node.rch = s[0]
            self.update(node)
            return (node, s[1])

    def insert(self, k, v):
        node = Node(v)
        l, r = self.split(self.root, k)
        self.root = self.merge(l, node)
        self.root = self.merge(self.root, r)
    
    def erase(self, k):
        e, r = self.split(self.root, k)
        l, e = self.split(e, k-1)
        self.root = self.merge(l, r)

    def add(self, v):
        k = self.floor_index(v) + 1
        self.insert(k, v)
    
    def remove(self, v):
        k = self.index(v) + 1
        self.erase(k)

    def index(self, value):
        def sub_index(node, k):
            if node is None:
                raise ValueError("{} is not in tree".format(value))
            nv = node.value
            if nv == value:
                return k + self.count(node.lch)
            if nv > value:
                return sub_index(node.lch, k)
            return sub_index(node.rch, k + self.count(node.lch) + 1)
        return sub_index(self.root, 0)

    def __getitem__(self, i):
        def sub_getitem(node, k):
            if node is None:
                raise IndexError("tree index out of range")
            lc = self.count(node.lch)
            if k + lc == i:
                return node.value
            if k + lc > i:
                return sub_getitem(node.lch, k)
            return sub_getitem(node.rch, k + lc + 1)
        return sub_getitem(self.root, 0)

    def floor_node(self, node, value, k):
        if node is None:
            return (None, None)

        nv = node.value
        if nv == value:
            return (nv, k + self.count(node.lch))
        if nv > value:
            return self.floor_node(node.lch, value, k)
        rf = self.floor_node(node.rch, value, k + self.count(node.lch) + 1)
        if rf[0] is None:
            return (nv, k + self.count(node.lch))
        return rf

    def ceil_node(self, node, value, k):
        if node is None:
            return (None, None)

        nv = node.value
        if nv == value:
            return (nv, k + self.count(node.lch))
        if nv < value:
            return self.ceil_node(node.rch, value, k + self.count(node.lch))
        lc = self.ceil_node(node.lch, value, k)
        if lc[0] is None:
            return (nv, k + self.count(node.lch))
        return lc
    
    def floor_value(self, node, value):
        if node is None:
            return None

        nv = node.value
        if nv == value:
            return nv
        if nv > value:
            return self.floor_value(node.lch, value)
        rf = self.floor_value(node.rch, value)
        if rf is None:
            return nv
        return rf

    def ceil_value(self, node, value):
        if node is None:
            return None

        nv = node.value
        if nv == value:
            return nv
        if nv < value:
            return self.ceil_value(node.rch, value)
        lc = self.ceil_value(node.lch, value)
        if lc is None:
            return nv
        return lc

    def floor(self, value):
        return self.floor_value(self.root, value)
    
    def ceil(self, value):
        return self.ceil_value(self.root, value)
    
    def floor_index(self, value):
        res = self.floor_node(self.root, value, 0)[1]
        if res is None:
            return -1
        return res
    
    def ceil_index(self, value):
        res = self.ceil_node(self.root, value, 0)[1]
        if res is None:
            return self.count(self.root)
        return res



def solve(N: int, a: "List[int]"):
    sep = Treap()
    sep.add(-1)
    sep.add(N)
    idx = {aa: i for i, aa in enumerate(a)}
    res = 0
    for n in range(1, N+1):
        i = idx[n]
        j = sep.floor(i)
        k = sep.ceil(i)
        res += n * (i - j) * (k - i)
        sep.add(i)
    print(res)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    a = [ int(next(tokens)) for _ in range(N) ]  # type: "List[int]"
    solve(N, a)

if __name__ == '__main__':
    main()


# Optimized solution
#!/usr/bin/env python3
import sys


def solve(N: int, a: "List[int]"):
    idx = {aa: i for i, aa in enumerate(a)}
    left = [i for i in range(N+2)]
    right = [i for i in range(N+2)]
    res = 0
    for n in range(N, 0, -1):
        i = idx[n]
        l = left[i]
        r = right[i]
        res += n * (i - l + 1) * (r - i + 1)
        left[r+1] = l
        right[l-1] = r
    print(res)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    a = [ int(next(tokens)) for _ in range(N) ]  # type: "List[int]"
    solve(N, a)

if __name__ == '__main__':
    main()