package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc *bufio.Scanner
var out *bufio.Writer

func main() {
	sc = bufio.NewScanner(os.Stdin)
	//bytes, _ := ioutil.ReadFile("./stdin.txt")
	//sc = bufio.NewScanner(strings.NewReader(string(bytes)))
	out = bufio.NewWriter(os.Stdout)
	buf := make([]byte, 1<<20)
	sc.Buffer(buf, bufio.MaxScanTokenSize)
	sc.Split(bufio.ScanWords)
	defer out.Flush()

	n := nextInt()
	a := nextInts(n)

	t := NewIntSegmentTree(n, intMin, 1<<31)
	for i := 0; i < n; i++ {
		t.node[i+t.size-1] = monoid1(a[i])
	}
	t.Build()

	var sum uint64 = 0
	search := func(a, b monoid1) bool { return a <= b }
	for i := 0; i < n; i++ {
		ls, rs := 0, n-1
		ai := t.node[i+t.size-1]
		if i > 0 {
			ls = t.SearchRight(0, i, ai, search)
			if ls == -1 {
				ls = 0
			} else {
				ls++
			}
		}
		if i < n-1 {
			rs = t.SearchLeft(i+1, n, ai, search)
			if rs == -1 {
				rs = n - 1
			} else {
				rs--
			}
		}
		sum += uint64((i - ls + 1) * (rs - i + 1) * int(ai))
	}
	fmt.Fprintln(out, sum)
}

func next() string {
	sc.Scan()
	return sc.Text()
}
func nextInt() int {
	a, _ := strconv.Atoi(next())
	return a
}
func nextInts(n int) []int {
	ret := make([]int, n)
	for i := 0; i < n; i++ {
		ret[i] = nextInt()
	}
	return ret
}
func intMin(a, b int) int {
	if a > b {
		return b
	}
	return a
}

type monoid1 int
type monoid2 monoid1

type SegmentTree struct {
	node []monoid1
	size int
	opNN func(monoid1, monoid1) monoid1
	en   monoid1
}

func NewIntSegmentTree(n int, nn func(int, int) int, en int) *SegmentTree {
	cnn := func(a monoid1, b monoid1) monoid1 {
		return monoid1(nn(int(a), int(b)))
	}
	return NewSegmentTree(n, cnn, monoid1(en))
}

func NewSegmentTree(n int, nn func(monoid1, monoid1) monoid1, en monoid1) *SegmentTree {
	size := 1
	for size < n {
		size <<= 1
	}
	t := &SegmentTree{
		node: make([]monoid1, 2*size-1),
		size: size,
		opNN: nn,
		en:   en,
	}
	for i := 0; i < size; i++ {
		k := i + size - 1
		t.node[k] = en
	}
	return t
}

func (t *SegmentTree) Build() {
	for k := t.size - 2; k >= 0; k-- {
		t.node[k] = t.opNN(t.node[2*k+1], t.node[2*k+2])
	}
}
func (t *SegmentTree) Update(i int, value monoid1) {
	k := i + t.size - 1
	t.node[k] = value
	for k > 0 {
		k = (k - 1) >> 1
		t.node[k] = t.opNN(t.node[2*k+1], t.node[2*k+2])
	}
}
func (t *SegmentTree) Query(a, b int) monoid1 {
	return t.querySub(a, b, 0, 0, t.size)
}
func (t *SegmentTree) querySub(a, b, k, l, r int) monoid1 {
	if b <= l || r <= a {
		return t.en
	}
	if a <= l && r <= b {
		return t.node[k]
	}
	vl := t.querySub(a, b, 2*k+1, l, (l+r)/2)
	vr := t.querySub(a, b, 2*k+2, (l+r)/2, r)
	return t.opNN(vl, vr)
}
func (t *SegmentTree) SearchLeft(a, b int, value monoid1, f func(monoid1, monoid1) bool) int {
	return t.searchLeftSub(a, b, value, f, 0, 0, t.size)
}
func (t *SegmentTree) searchLeftSub(a, b int, value monoid1, f func(monoid1, monoid1) bool, k, l, r int) int {
	if !f(t.node[k], value) || b <= l || r <= a {
		return -1
	}
	if k >= t.size-1 {
		return k - (t.size - 1)
	}
	vl := t.searchLeftSub(a, b, value, f, 2*k+1, l, (l+r)/2)
	if vl != -1 {
		return vl
	}
	return t.searchLeftSub(a, b, value, f, 2*k+2, (l+r)/2, r)
}
func (t *SegmentTree) SearchRight(a, b int, value monoid1, f func(monoid1, monoid1) bool) int {
	return t.searchRightSub(a, b, value, f, 0, 0, t.size)
}
func (t *SegmentTree) searchRightSub(a, b int, value monoid1, f func(monoid1, monoid1) bool, k, l, r int) int {
	if !f(t.node[k], value) || b <= l || r <= a {
		return -1
	}
	if k >= t.size-1 {
		return k - (t.size - 1)
	}
	vr := t.searchRightSub(a, b, value, f, 2*k+2, (l+r)/2, r)
	if vr != -1 {
		return vr
	}
	return t.searchRightSub(a, b, value, f, 2*k+1, l, (l+r)/2)
}


Measured memory_bytes: 10076