Score: 400 points

Problem Statement:
One day, Snuke was given a permutation of length N, a_1, a_2, ..., a_N, from his friend. Find the following:

Constraints:
- 1 ≦ N ≦ 200,000
- (a_1, a_2, ..., a_N) is a permutation of (1, 2, ..., N).

Input:
The input is given from Standard Input in the following format:
N
a_1 a_2 ... a_N

Output:
Print the answer.
Note that the answer may not fit into a 32-bit integer.

Sample Input 1:
3
2 1 3

Sample Output 1:
9

Sample Input 2:
4
1 3 2 4

Sample Output 2:
19

Sample Input 3:
8
5 4 8 1 2 6 7 3

Sample Output 3:
85

# Buggy version:
# B - Minimum Sum
N = int(input())
A = list(enumerate(list(map(int,input().split()))))
left = [i-1 for i in range(N)]
right = [i+1 for i in range(N)]
A.sort(key=lambda x:x[1],reverse=True)
ans = 0
for i,a in A:
    il,ir = left[i],right[i]
    ans += a*(i-il)*(ir-i)
    if ir<N:
        left[ir] = il
    if il>0:
        right[il] = ir
print(ans)

# Fixed version:
# B - Minimum Sum
N = int(input())
A = list(enumerate(list(map(int,input().split()))))
left = [i-1 for i in range(N)]
right = [i+1 for i in range(N)]
A.sort(key=lambda x:x[1],reverse=True)
ans = 0
for i,a in A:
    il,ir = left[i],right[i]
    ans += a*(i-il)*(ir-i)
    if ir<N:
        left[ir] = il
    if il>-1:
        right[il] = ir
print(ans)

# Buggy version:
import sys
from operator import itemgetter

n, *aaa = map(int, sys.stdin.buffer.read().split())
aaa_with_index = list(enumerate(aaa, start=1))
aaa_with_index.sort(key=itemgetter(1), reverse=True)
left = list(range(n + 2))
right = left.copy()
ans = 0
for i, a in aaa_with_index:
    li = left[i]
    ri = right[i]
    ans += a * (i - li + 1) * (ri - i + 1)
    left[right[i + 1]] = li
    right[left[i - 1]] = ri

print(ans)


# Fixed version:
import sys
from operator import itemgetter

n, *aaa = map(int, sys.stdin.buffer.read().split())
aaa_with_index = list(enumerate(aaa, start=1))
aaa_with_index.sort(key=itemgetter(1), reverse=True)
left = list(range(-1, n + 1))
right = list(range(1, n + 3))
ans = 0
for i, a in aaa_with_index:
    li = left[i]
    ri = right[i]
    ans += a * (i - li) * (ri - i)
    left[ri] = li
    right[li] = ri

print(ans)

# Buggy version:
class BIT:
  def __init__(self,n):
    self.N = n
    self.data = [0]*(N+1)
  def bit_add(self,i,a):
    j = i+1
    while j<=N:
      self.data[j] += a
      j += j&-j
  def bit_sum(self,i):
    m = 0
    j = i+1
    while j>0:
      m += self.data[j]
      j -= j&-j
    return m
  def bit_search(self,x):
    i = 0
    m = 0
    j = 1<<(self.N.bit_length()-1)
    while j:
      if i+j<=N and self.data[i+j]+m<=x:
        i += j
        m += self.data[i]
      j >>= 1
    return i
N, *A = map(int, open('0').read().split())
bit = BIT(N)
ntoi = [0]*(N+1)
ans = 0
for i, a in enumerate(A):
  ntoi[a] = i
for i in range(1,N+1):
  j = ntoi[i]
  L = bit.bit_sum(j)
  R = N-L-1
  if L!=0:
    a = bit.bit_search(L-1)
  else:
    a = -1
  if R!=0:
    b = bit.bit_search(L)
  else:
    b = N
  ans += (j-a)*(b-j)*i
  bit.bit_add(j,1)
print(ans)

# Fixed version:
class BIT:
  def __init__(self,n):
    self.N = n
    self.data = [0]*(N+1)
  def bit_add(self,i,a):
    j = i+1
    while j<=N:
      self.data[j] += a
      j += j&-j
  def bit_sum(self,i):
    m = 0
    j = i+1
    while j>0:
      m += self.data[j]
      j -= j&-j
    return m
  def bit_search(self,x):
    i = 0
    m = 0
    j = 1<<(self.N.bit_length()-1)
    while j:
      if i+j<=N and self.data[i+j]+m<=x:
        i += j
        m += self.data[i]
      j >>= 1
    return i
N, *A = map(int, open(0).read().split())
bit = BIT(N)
ntoi = [0]*(N+1)
ans = 0
for i, a in enumerate(A):
  ntoi[a] = i
for i in range(1,N+1):
  j = ntoi[i]
  L = bit.bit_sum(j)
  R = N-L-1
  if L!=0:
    a = bit.bit_search(L-1)
  else:
    a = -1
  if R!=0:
    b = bit.bit_search(L)
  else:
    b = N
  ans += (j-a)*(b-j)*i
  bit.bit_add(j,1)
print(ans)

# Buggy version:
def main():
    n = int(input())
    a = list(map(int, input().split()))
    a = sorted(list(enumerate(a)), key=lambda x: -x[1])
    L = [i for i in range(n+2)]  # 連結成分のうち一番左のindex
    R = [i for i in range(n+2)]  # 連結成分のうち一番右のindex
    ans = 0
    for i, j in a:  # 1-indexなので1ずれる
        print(L, R)
        M = R[i+1]  # 連結成分の最大値
        m = L[i+1]  # 連結成分の最小値
        ans += j*(M-i)*(i+2-m)  # 計算
        R[m-1] = M  # 連結成分の左端の更新
        L[M+1] = m  # 連結成分の右端の更新
    print(ans)


main()

# Fixed version:
def main():
    n = int(input())
    a = list(map(int, input().split()))
    a = sorted(list(enumerate(a)), key=lambda x: -x[1])
    L = [i for i in range(n+2)]  # 連結成分のうち一番左のindex
    R = [i for i in range(n+2)]  # 連結成分のうち一番右のindex
    ans = 0
    for i, j in a:  # 1-indexなので1ずれる
        M = R[i+1]  # 連結成分の最大値
        m = L[i+1]  # 連結成分の最小値
        ans += j*(M-i)*(i+2-m)  # 計算
        R[m-1] = M  # 連結成分の左端の更新
        L[M+1] = m  # 連結成分の右端の更新
    print(ans)


main()

# Buggy version:
N=int(input())
a=list(map(int,input().split()))

l=[]
r=[]
s=[]

for i,x in enumerate(a):
  left=i
  if len(s)>0 and x<s[-1][0]:
    left=s[-1][-1]
    s.pop()
  l.append(left)
  s.append([x,left])
  #print(l)
  #print(s)
s=[]
for i in range(N-1,-1,-1):
  right=i
  x=a[i]
  if len(s)>0 and x<s[-1][0]:
    right=s[-1][-1]
    s.pop()
  r.append(right)
  s.append([x,right])
r=r[::-1]
ans=0
for i,(x,le,ri) in enumerate(zip(a,l,r)):
  ans+=x*(i-le+1)*(ri-i+1)
print(ans)

# Fixed version:
N=int(input())
a=list(map(int,input().split()))

l=[]
r=[]
s=[]

for i,x in enumerate(a):
  left=i
  while len(s)>0 and x<s[-1][0]:
    left=s[-1][-1]
    s.pop()
  l.append(left)
  s.append([x,left])
  #print(l)
  #print(s)
s=[]
for i in range(N-1,-1,-1):
  right=i
  x=a[i]
  while len(s)>0 and x<s[-1][0]:
    right=s[-1][-1]
    s.pop()
  r.append(right)
  s.append([x,right])
r=r[::-1]
ans=0
for i,(x,le,ri) in enumerate(zip(a,l,r)):
  ans+=x*(i-le+1)*(ri-i+1)
print(ans)

# Buggy version:
n = int(input())
a = list(map(int, input().split()))
d = {}
for i,j in enumerate(a):
    d[j] = i

uf = [-1]*n
def root(a):
    if uf[a] < 0:
        return a
    uf[a] = root(uf[a])
    return uf[a]
def unite(a,b):
    ra,rb = root(a),root(b)
    if ra==rb:
        return False
    if uf[ra] > uf[rb]:
        ra,rb = rb,ra
    uf[ra] += uf[rb]
    uf[rb] = ra
    return True

ans = 0
for i in range(n,0,-1):
    left=right=0
    ind = d[i]

    if ind<n-1 and a[ind] < a[ind+1]:
        right -= uf[ind+1]
        unite(ind, ind+1)
    if ind>0 and a[ind] < a[ind-1]:
        left -= uf[ind-1]
        unite(ind, ind-1)
    ans += i*(left+1)*(right+1)

print(ans)

# Fixed version:
n = int(input())
a = list(map(int, input().split()))
d = {}
for i,j in enumerate(a):
    d[j] = i

uf = [-1]*n
def root(a):
    if uf[a] < 0:
        return a
    uf[a] = root(uf[a])
    return uf[a]
def unite(a,b):
    ra,rb = root(a),root(b)
    if ra==rb:
        return False
    if uf[ra] > uf[rb]:
        ra,rb = rb,ra
    uf[ra] += uf[rb]
    uf[rb] = ra
    return True

ans = 0
for i in range(n,0,-1):
    left=right=0
    ind = d[i]

    if ind<n-1 and a[ind] < a[ind+1]:
        right -= uf[root(ind+1)]
        unite(ind, ind+1)
    if ind>0 and a[ind] < a[ind-1]:
        left -= uf[root(ind-1)]
        unite(ind, ind-1)
    ans += i*(left+1)*(right+1)

print(ans)

# Buggy version:
import sys
sys.setrecursionlimit(10**7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return input()

from collections import Counter

def main():
    N = II()
    A = LI()
    idxs = [0] * (N + 1)
    for i, a in enumerate(A):
        idxs[a] = i
    ll = list(range(N + 1))
    rr = list(range(N + 1))
    ans = 0
    for a in range(N, 0, -1):
        idx = idxs[a]
        l, r = ll[idx], rr[idx]
        ans += (idx - l + 1) * (r - idx + 1) * a
        ll[idx + 1] = l
        rr[idx - 1] = r

    return ans

print(main())

# Fixed version:
import sys
sys.setrecursionlimit(10**7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return input()

from collections import Counter

def main():
    N = II()
    A = LI()
    idxs = [0] * (N + 1)
    for i, a in enumerate(A):
        idxs[a] = i
    ll = list(range(N + 1))
    rr = list(range(N + 1))
    ans = 0
    for a in range(N, 0, -1):
        idx = idxs[a]
        l, r = ll[idx], rr[idx]
        ans += (idx - l + 1) * (r - idx + 1) * a
        ll[r + 1] = l
        rr[l - 1] = r

    return ans

print(main())

# Buggy version:
import heapq

n = int(input())
alist = list(map(int, input().split()))

ad = {}
for i, a in enumerate(alist):
  ad[a] = i

h = []
right = [n-1] * n

for i in range(n):
  while h and -h[0] > alist[i]:
    v = -heapq.heappop(h)
    right[ad[v]] = i - 1
  heapq.heappush(h, -alist[i])
  print(right, h)

h = []
left = [0] * n

for i in reversed(range(n)):
  while h and -h[0] > alist[i]:
    v = -heapq.heappop(h)
    left[ad[v]] = i + 1
  heapq.heappush(h, -alist[i])
  print(left, h)

ans = 0
for i in range(n):
  ans += alist[i] * (i - left[i] + 1) * (right[i] - i + 1)
  print(ans)

print(ans)


# Fixed version:
import heapq


n = int(input())
a = list(map(int, input().split()))

d = {}
for i, a_ in enumerate(a):
    d[a_] = i


h = []
right = [n-1] * n

for i in range(n):
    while h and -h[0] > a[i]:
        v = -heapq.heappop(h)
        right[d[v]] = i - 1
    heapq.heappush(h, -a[i])

h = []
left = [0] * n

for i in reversed(range(n)):
    while h and -h[0] > a[i]:
        v = -heapq.heappop(h)
        left[d[v]] = i + 1
    heapq.heappush(h, -a[i])

ans = 0
for i in range(n):
    ans += a[i] * (i - left[i] + 1) * (right[i] - i + 1)

print(ans)

# Buggy version:
# def makelist(n, m):
# 	return [[0 for i in range(m)] for j in range(n)]

# a = int(input())
# b, c = map(int, input().split())
# s = input()


par = [0]*202020
size = [0]*202020

def find(x):
	if par[x] == x:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	x = find(x)
	y = find(y)
	res = size[x] * size[y]
	size[x] += size[y]
	par[y] = x
	return res

# main
n = int(input())
for i in range(202020):
	par[i] = i
	size[i] = 1

a = [0] + list(map(int, input().split()))
b = [0]*(n+1)
for i in range(1, n+1):
	b[a[i]] = i

ans = 0
for j in reversed(1, n+1):
	i = b[j]
	ans += a[i]
	if i - 1 >= 1 and a[i-1] > a[i]:
		ans += unite(i-1, i) * a[i]
	if i + 1 <= n and a[i+1] > a[i]:
		ans += unite(i+1, i) * a[i]
print(ans)


# Fixed version:
# def makelist(n, m):
# 	return [[0 for i in range(m)] for j in range(n)]

# a = int(input())
# b, c = map(int, input().split())
# s = input()


par = [0]*202020
size = [0]*202020

def find(x):
	if par[x] == x:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	x = find(x)
	y = find(y)
	res = size[x] * size[y]
	size[x] += size[y]
	par[y] = x
	return res

# main
n = int(input())
for i in range(202020):
	par[i] = i
	size[i] = 1

a = [0] + list(map(int, input().split()))
b = [0]*(n+1)
for i in range(1, n+1):
	b[a[i]] = i

ans = 0
for j in reversed(range(1, n+1)):
	i = b[j]
	ans += a[i]
	if i - 1 >= 1 and a[i-1] > a[i]:
		ans += unite(i-1, i) * a[i]
	if i + 1 <= n and a[i+1] > a[i]:
		ans += unite(i+1, i) * a[i]
print(ans)