Problem:
 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

Solution (Python):

import sys
def main(N, A):
    ans = 0
    Ai = [(a, i + 1) for i, a in enumerate(A)]
    Ai.sort(key=lambda x: x[0])
    st = SegmentTree(n=N + 2, f=lambda x, y: x + y)
    st.set_val(0, 1)
    st.set_val(N + 1, 1)
    for a, i in Ai:
        lc = st.query(0, i)
        l = st.bisect_left(lambda x: x < lc)
        r = st.bisect_left(lambda x: x < lc + 1)
        ans += a * (i - l) * (r - i)
        st.set_val(i, 1)
    print(ans)

class SegmentTree:
    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i << 1], d[i << 1 | 1])

    def get_val(self, index):
        return self.__d[index + self.__n]

    def set_val(self, index, new_value):
        i, d, f = index + self.__n, self.__d, self.__f
        if d[i] == new_value: return
        d[i], i = new_value, i >> 1
        while i:
            d[i], i = f(d[i << 1], d[i << 1 | 1]), i >> 1

    def modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

    def query(self, from_inclusive, to_exclusive):
        ans = self.__e()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__d, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l + 1
            if r & 1: ans, r = f(d[r - 1], ans), r - 1
            l, r = l >> 1, r >> 1
        return ans

    def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, j, n, f, d, v = self.__n, self.__n + self.__n, self.__n, self.__f, self.__d, self.__e()
        while i < j:
            if i & 1:
                nv = f(v, d[i])
                if not func(nv): break
                v, i = nv, i + 1
            i, j = i >> 1, j >> 1
        while i < n:
            nv = f(v, d[i << 1])
            if func(nv): v, i = nv, i << 1 | 1
            else: i = i << 1
        return i - n

if __name__ == '__main__':
    input = sys.stdin.readline
    N = int(input())
    *A, = map(int, input().split())
    main(N, A)

Solution (Python):

import sys
def main(N, A):
    ans = 0
    Ai = [(a, i + 1) for i, a in enumerate(A)]
    Ai.sort(key=lambda x: x[0])
    st = SegmentTree(n=N + 2, f=lambda x, y: x + y)
    st.set_val(0, 1)
    st.set_val(N + 1, 1)
    for a, i in Ai:
        lc = st.query(0, i)
        l = st.bisect_left(lambda x: x < lc)
        r = st.bisect_left(lambda x: x < lc + 1)
        ans += a * (i - l) * (r - i)
        st.set_val(i, 1)
    print(ans)

class SegmentTree:
    def __init__(self, n=None, f=max, identity_factory=int, initial_values=None):
        assert(n or initial_values)
        size = n if n else len(initial_values)
        d = [identity_factory() for _ in range(2 * size + 1)]
        self.__n, self.__d, self.__f, self.__e = size, d, f, identity_factory
        if initial_values:
            for i, v in enumerate(initial_values): d[size + i] = v
            for i in range(size - 1, 0, -1): d[i] = f(d[i << 1], d[i << 1 | 1])

    def get_val(self, index):
        return self.__d[index + self.__n]

    def set_val(self, index, new_value):
        i, d, f = index + self.__n, self.__d, self.__f
        if d[i] == new_value: return
        d[i] = new_value
        i = i >> 1
        while i:
            d[i] = f(d[i << 1], d[i << 1 | 1])
            i = i >> 1

    def modify(self, index, value):
        self.set_val(index, self.__f(self.__d[index + self.__n], value))

    def query(self, from_inclusive, to_exclusive):
        ans = self.__e()
        if to_exclusive <= from_inclusive: return ans
        l, r, d, f = from_inclusive + self.__n, to_exclusive + self.__n, self.__d, self.__f
        while l < r:
            if l & 1: ans, l = f(ans, d[l]), l + 1
            if r & 1: ans, r = f(d[r - 1], ans), r - 1
            l, r = l >> 1, r >> 1
        return ans

    def bisect_left(self, func):
        '''func()がFalseになるもっとも左のindexを探す
        '''
        i, n, f, d, v = 1, self.__n, self.__f, self.__d, self.__e()
        i = n
        j = n + n
        while i < j:
            if i & 1:
                nv = f(v, d[i])
                if not func(nv):
                    break
                v = nv
                i += 1
            i >>= 1
            j >>= 1
        while i < n:
            nv = f(v, d[i << 1])
            if func(nv):
                v, i = nv, i << 1 | 1
            else:
                i = i << 1
        return i - n

if __name__ == '__main__':
    input = sys.stdin.readline
    N = int(input())
    *A, = map(int, input().split())
    main(N, A)

Solution (Python):
''' 
    [Bit]
'''
class Bit:
    """ used for only int(>=0) 
        1-indexed (ignore 0-index)
    """
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
        self.depth = n.bit_length()
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def lower_bound(self, x):
        """ 累積和がx以上になる最小のindexと、その直前までの累積和 """
        sum_ = 0
        pos = 0
        for i in range(self.depth, -1, -1):
            k = pos + (1 << i)
            if k <= self.size and sum_ + self.tree[k] < x:
                sum_ += self.tree[k]
                pos += 1 << i
        return pos + 1, sum_

    def get_less_than_x_cnt(self, x):
        """ 累積和がx未満 の個数 """
        lb_pos, lb_sum = self.lower_bound(x)
        return lb_pos-1

    def get_less_than_and_x_cnt(self, x):
        """ 累積和がx以下 の個数 """
        lb_pos, lb_sum = self.lower_bound(x+1)
        return lb_pos-1
    
    def get_more_than_x_cnt(self, x):
        """ 累積和がxより大きい 個数 """
        return self.size - self.get_less_than_and_x_cnt(x)


n = int(input())
al = list(map(int, input().split()))
bit = Bit(n)

a_to_i = [0]*(n+1)
for i,a in enumerate(al):
    a_to_i[a] = i+1

ans = 0
for a in range(1,n+1):
    curr_i = a_to_i[a]
    all_left_cnt = bit.sum(curr_i)
    if all_left_cnt == 0:
        left_cnt = curr_i
    else:
        left_i, _ = bit.lower_bound(all_left_cnt)
        left_cnt = curr_i - left_i

    right_i, _ = bit.lower_bound(all_left_cnt+1)
    right_cnt = right_i - curr_i
    all_cnt = right_cnt*left_cnt
    a_sum = a*all_cnt
    ans += a_sum
    bit.add(curr_i,1)

    

print(ans)

Solution (Python):
class BIT:
	"0-indexed apparently"
	
	def __init__(self, n):
		self.n = n
		self.data = [0] * (n+1)
		
	def point_add(self, index, value):
		index += 1
		while index <= self.n:
			self.data[index] += value
			index += index & -index
		
	def folded(self, r):
		"[0, r)"
		ret = 0
		while r > 0:
			ret += self.data[r]
			r -= r & -r
		return ret
		
	def bisect_left(self, value):
		index = 0
		k = 1 << ((self.n + 1).bit_length() - 1)
		while k > 0:
			if index + k <= self.n and self.data[index + k] < value:
				value -= self.data[index + k]
				index += k
			k >>= 1
		return index + 1
		
N = int(input())
As = list(map(int, input().split()))

A_inv = [0] * N
for i, A in enumerate(As):
	A_inv[A-1] = i
	
bit = BIT(N + 2)
bit.point_add(0, 1)
bit.point_add(N+1, 1)
ans = 0
for A, index in enumerate(A_inv):
	A += 1
	index += 1
	v = bit.folded(index)
	ans += A * (bit.bisect_left(v+1) - index - 1) * (index - bit.bisect_left(v) + 1)
	
	bit.point_add(index, 1)
	
print(ans)

Solution (Python):
'''
研究室PCでの解答
'''
import math

import queue
import bisect
from collections import deque,defaultdict
import heapq as hpq
from sys import stdin,setrecursionlimit


ipt = stdin.readline
setrecursionlimit(10**7)
mod = 10**9+7
dir = [(-1,0),(1,0),(0,-1),(0,1)]
alp = "abcdefghijklmnopqrstuvwxyz"

def main():
    n = int(ipt())
    ans = 0
    a = [int(i) for i in ipt().split()]
    pl = [-1]*(n+1)
    for i,ai in enumerate(a):
        pl[ai] = i+1

    
    
    BIT = [0]*(n+1)

    
    def BIT_query(idx):
        res_sum = 0
        while idx > 0:
            res_sum += BIT[idx]
            idx -= idx&(-idx)
        return res_sum

    
    def BIT_update(idx,x):
        while idx <= n:
            BIT[idx] += x
            idx += idx&(-idx)
        return

    for i in range(1,n+1):
        pi = pl[i]
        ll = 0
        lr = pi
        bi = BIT_query(pl[i])
        while ll != lr:
            mid = ll+(lr-ll)//2
            if BIT_query(mid) == bi:
                lr = mid
            else:
                ll = mid+1
        rl = pi
        rr = n
        while rl != rr:
            mid = rl+(rr-rl+1)//2
            if BIT_query(mid) == bi:
                rl = mid
            else:
                rr = mid-1

        ans += (pi-lr)*(rl-pi+1)*i
        BIT_update(pi,1)

    print(ans)

    return None

if __name__ == '__main__':
    main()

Solution (Python):
'''
研究室PCでの解答
'''
import math

import queue
import bisect
from collections import deque,defaultdict
import heapq as hpq
from sys import stdin,setrecursionlimit


ipt = stdin.readline
setrecursionlimit(10**7)
mod = 10**9+7
dir = [(-1,0),(1,0),(0,-1),(0,1)]
alp = "abcdefghijklmnopqrstuvwxyz"

class Binary_Indexed_Tree:
    
    
    def __init__(self,n):
        self.N = n
        self.BIT = [0]*(n+1)
        self.l2 = 2**(len(format(n,'b'))-1)

    
    def query(self,idx):
        res_sum = 0
        while idx > 0:
            res_sum += self.BIT[idx]
            idx -= idx&(-idx)
        return res_sum

    
    def update(self,idx,x):
        while idx <= self.N:
            self.BIT[idx] += x
            idx += idx&(-idx)
        return

    def lower_bound(self,w):
        if w <= 0:
            return 0
        x = 0
        k = self.l2
        while k > 0:
            if x+k <= self.N and self.BIT[x+k] < w:
                w -= self.BIT[x+k]
                x += k
            k //= 2
        return x+1

    def upper_bound(self,w):
        x = 0
        k = self.l2
        while k > 0:
            if x+k <= self.N and self.BIT[x+k] <= w:
                w -= self.BIT[x+k]
                x += k
            k //= 2
        return x

def main():
    n = int(ipt())
    ans = 0
    a = [int(i) for i in ipt().split()]
    pl = [-1]*(n+1)
    for i,ai in enumerate(a):
        pl[ai] = i+1

    bt = Binary_Indexed_Tree(n)

    for i in range(1,n+1):
        pi = pl[i]
        bi = bt.query(pl[i])
        lb = bt.lower_bound(bi)
        ub = bt.upper_bound(bi)
        ans += (pi-lb)*(ub-pi+1)*i
        bt.update(pi,1)

    print(ans)

    return None

if __name__ == '__main__':
    main()

Solution (Python):
n = int(input())
a = list(map(int, input().split()))
l = [0] * (n + 1)
l2 = list(range(n + 2))
l3 = list(range(n + 2))
ans = 0
for i in range(n):
    l[a[i]] = i
for i in range(1, n + 1)[::-1]:
    x, y = l2[l[i]], l3[l[i]]
    ans += (l[i] - x + 1) * (y - l[i] + 1) * i
    l2[y + 1], l3[x - 1] = x, y
print(ans)

Solution (Python):
class BIT:
    def __init__(self,N):
        self.N=N
        self.bit=[0]*(N+1)
        self.b=1<<N.bit_length()-1
    def add(self,a,w):
        x=a
        while(x<=self.N):
            self.bit[x]+=w
            x+=x&-x
    def get(self,a):
        ret,x=0,a-1
        while(x>0):
            ret+=self.bit[x]
            x-=x&-x
        return ret
    def cum(self,l,r):
        return self.get(r)-self.get(l) 
    def lowerbound(self,w):
        if w<=0:
            return 0
        x=0
        k=self.b
        while k>0:
            if x+k<=self.N and self.bit[x+k]<w:
                w-=self.bit[x+k]
                x+=k
            k//=2
        return x+1

N=int(input())
A=list(map(int,input().split()))
dic={}
for i in range(N):
    dic[A[i]]=i+1
bit=BIT(N)
ans=0
for i in range(1,N+1):
    d=dic[i]
    bit.add(d,1)
    c=bit.get(d+1)
    L=bit.lowerbound(c-1)
    R=bit.lowerbound(c+1)
    ans+=(R-d)*(d-L)*i
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
import bisect

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

class Bit:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
  
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
  
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

B = [[A[i], i] for i in range(n)]
B.sort()

L = Bit(n)
R = Bit(n)
ans = 0
for i in range(n):
    l = -1
    r = n+1
    m = (l+r)//2
    while r-l > 1:
        
        if L.sum(m) < L.sum(B[i][1]+1):
            l = m
        else:
            r = m
        m = (l+r)//2
    
    L.add(B[i][1]+1, 1)
    
    
    LL = l

    rr = n-1-B[i][1]
    l = -1
    r = n+1
    m = (l+r)//2
    while r-l > 1:
        
        if R.sum(m) < R.sum(rr+1):
            l = m
        else:
            r = m
        m = (l+r)//2
    
    R.add(n-1-B[i][1]+1, 1)
    
    RR = l

    ans += B[i][0] * (B[i][1]-LL) * ((n-1-RR)-B[i][1])
    
print(ans)

Solution (Python):
def make_tree(n):
    i = 2
    while True:
        if i >= n * 2:
            tree = [-1] * i
            break
        else:
            i *= 2
    return tree

def initialization(a):
    l = len(tree) // 2
    for i in range(l, l + len(a)):
        tree[i] = a[i - l]
    for i in range(l - 1, 0, -1):
        tree[i] = max(tree[2 * i], tree[2 * i + 1])
    return

def update(i, x):
    i += len(tree) // 2
    tree[i] = x
    i //= 2
    while True:
        if i == 0:
            break
        tree[i] = max(tree[2 * i], tree[2 * i + 1])
        i //= 2
    return

def find(s, t):
    s += len(tree) // 2
    t += len(tree) // 2
    ans = -1
    while True:
        if s > t:
            break
        if s % 2 == 0:
            s //= 2
        else:
            ans = max(ans, tree[s])
            s = (s + 1) // 2
        if t % 2 == 1:
            t //= 2
        else:
            ans = max(ans, tree[t])
            t = (t - 1) // 2
    return ans

n = int(input())
a = list(map(int, input().split()))
x1, x2 = [0] * n, [0] * n
tree = make_tree(n)
for i in range(n):
    update(a[i] - 1, i)
    x1[i] = find(0, a[i] - 2)
initialization([-1] * n)
for i in range(n):
    j = n - i - 1
    update(a[j] - 1, i)
    x2[j] = n - find(0, a[j] - 2) - 1
ans = 0
for i in range(n):
    ans += a[i] * (i - x1[i]) * (x2[i] - i)
print(ans)

Solution (Python):
import bisect
import copy
import heapq
import math
import sys
from collections import *
from functools import lru_cache
from itertools import accumulate, combinations, permutations, product
def input():
    return sys.stdin.readline()[:-1]
def ruiseki(lst):
    return [0]+list(accumulate(lst))
sys.setrecursionlimit(500000)
mod=pow(10,9)+7
al=[chr(ord('a') + i) for i in range(26)]
direction=[[1,0],[0,1],[-1,0],[0,-1]]

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

dic={}
for i in range(n):
    dic[a[i]]=i+1


class BIT:
    def __init__(self, n):
        self.n = n
        self.data = [0]*(n+1)
        self.el = [0]*(n+1)
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.data[i]
            i -= i & -i
        return s
    def add(self, i, x):
        
        self.el[i] += x
        while i <= self.n:
            self.data[i] += x
            i += i & -i
    def get(self, i, j=None):
        if j is None:
            return self.el[i]
        return self.sum(j) - self.sum(i)

bi=BIT(n)
ans=0

for i in range(n):
    lsum=bi.sum(dic[i+1])
    l,r=-1,dic[i+1]
    while r-l>1:
        half=(r+l)//2
        if bi.sum(half)>=lsum:
            r=half
        else:
            l=half
    ll=r
    rsum=bi.get(dic[i+1],n)
    l,r=dic[i+1],n+1
    while r-l>1:
        half=(r+l)//2
        if bi.get(half,n)>=rsum:
            l=half
        else:
            r=half
    rr=l
    ans+=(i+1)*(dic[i+1]-ll)*(rr-dic[i+1]+1)
    
    bi.add(dic[i+1],i+1)
    
    
print(ans)

Solution (Python):
import sys

readline = sys.stdin.readline
MOD = 10 ** 9 + 7
INF = float('INF')
sys.setrecursionlimit(10 ** 5)


class BinaryIndexTree:
    def __init__(self, n):
        self.size = n
        self._container = [0] * (n + 1)
        self.depth = n.bit_length()

    def sum(self, i):
        if i == 0:
            return 0
        s = 0
        while i > 0:
            s += self._container[i]
            i -= i & (-i)
        return s

    def add(self, i, x):
        if i == 0:
            return
        while i <= self.size:
            self._container[i] += x
            i += i & (-i)

    def lower_bound(self, x):
        if x == 0:
            return 0

        s = 0
        idx = 0
        for i in range(self.depth, -1, -1):
            k = idx + (1 << i)
            if k <= self.size and s + self._container[k] < x:
                s += self._container[k]
                idx += 1 << i
        return idx + 1

    def __repr__(self):
        return str(self._container)


def main():
    n = int(readline())
    a = list(map(int, readline().split()))
    idx = dict()
    for i, x in enumerate(a, 1):
        idx[x] = i

    bt = BinaryIndexTree(n + 1)
    bt.add(n + 1, 1)
    ans = 0
    for num in range(1, n + 1):
        i = idx[num]
        s = bt.sum(i)
        left = bt.lower_bound(s)
        right = bt.lower_bound(s + 1)
        ans += num * (i - left) * (right - i)
        bt.add(i, 1)

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


n = int(input())
a = list(map(int, input().split()))
d = {}
for i,num in enumerate(a):
    d[num] = i+1
ans = 0


def init(bit, values):
    for i,v in enumerate(values):
        add(bit,i+1,v)

def query(bit,i):
    res = 0
    while i > 0:
        res += bit[i]
        i -= i&(-i)
    return res


def add(bit,i,x):
    if i==0:
        raise RuntimeError
    while i <= len(bit)-1:
        bit[i] += x
        i += i&(-i)
    return


def index(bit, v):
    i = 0
    k = 1
    n = len(bit)-1
    while 2*k<n:
        k *= 2
    while k>0:
        if i+k<n+1 and bit[i+k]<v:
            v -= bit[i+k]
            i += k
        k //= 2
    return i+1
bit = [0] * (n+2)
bit[n+1] = 1
for num in range(1,n+1):
    v = query(bit, d[num])
    v1 = index(bit, v) if v>0 else 0
    v2 = index(bit, v+1)
    ans += num * (d[num]-v1) * (v2 - d[num])

    add(bit, d[num], 1)
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
N = int(input())
A = list(map(int,input().split()))

class SegmentTree:
    def __init__(self,data,op,default):
        N = len(data)
        self.N = N
        self.op = op
        self.default = default
        self.l = 2**((N-1).bit_length())
        self.data = [default]*self.l + data + [default]*(self.l-N)
        for i in range(self.l-1,0,-1):
            self.data[i] = op(self.data[2*i], self.data[2*i+1])

    def get_data(self):
        return self.data[self.l:self.l + self.N]

    def set(self,i,val):
        i += self.l
        self.data[i] = val
        i = i//2
        while i > 0:
            self.data[i] = self.op(self.data[2*i], self.data[2*i+1])
            i = i//2

    def get(self,i,j):
        i += self.l
        j += self.l
        s = self.default 
        while j-i > 0:
            if i & 1:
                s = self.op(s,self.data[i])
                i += 1
            if j & 1:
                s = self.op(s,self.data[j-1])
                j -= 1
            i = i//2
            j = j//2
        return s

AI = [(a,i) for i,a in enumerate(A)]

inf = 10**10
seg = SegmentTree(AI,min,(inf,inf))

cand = [(0,N)]

ans = 0
while cand:
    temp = []
    for l,r in cand:
        m, i = seg.get(l,r)
        ans += m * (i-l+1) * (r-i)
        if l < i:
            temp.append([l,i])
        if i+1 < r:
            temp.append([i+1,r])
    cand = temp

print(ans)

Solution (Python):
n = int(input())
a = [int(x) for x in input().split()]
index = [0]*n
for i in range(n):
    index[a[i]-1] = i+2


class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s

    def add(self, i, x):
        if i == 0:
            print("Oops! BIT is an 1-indexed tree.")
            exit()
        while i <= self.size:
            self.tree[i] += x
            i += i & -i


ans = 0
s = BIT(n+2)
s.add(1, -1)
s.add(n+2, 1)
for i in range(n):
    s.add(index[i], 1)

    left = s.sum(index[i]) - 1
    bottom = 1
    top = index[i]
    while top - bottom > 1:
        middle = (top+bottom)//2
        if s.sum(middle) >= left:
            top = middle
        else:
            bottom = middle
    if left == -1:
        left = 1
    else:
        left = top

    right = s.sum(index[i])+1
    bottom = index[i]
    top = n+2
    while top - bottom > 1:
        middle = (top+bottom)//2
        if s.sum(middle) >= right:
            top = middle
        else:
            bottom = middle
    right = top

    ans += (i+1)*(index[i]-left)*(right-index[i])

print(ans)

Solution (Python):
import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

def maximal_rectangle(H):
    """ヒストグラムに対して、極大長方形を計算。
    各 i に対して、[l,r) が高さ H[i] となるような l, r を計算する。
    アリ本 p.299～p.300
    """
    N = len(H)
    L = np.empty(N, np.int32)
    R = np.empty(N, np.int32)
    st = np.zeros(N, np.int32)
    
    t = 0
    for i in range(N):
        while t and H[st[t - 1]] >= H[i]:
            t -= 1
        L[i] = 0 if t == 0 else st[t - 1] + 1
        st[t] = i
        t += 1
    
    t = 0
    for i in range(N - 1, -1, -1):
        while t and H[st[t - 1]] >= H[i]:
            t -= 1
        R[i] = N if t == 0 else st[t - 1]
        st[t] = i
        t += 1
    return L, R

signature = '(i8[:],)'
if sys.argv[-1] == 'ONLINE_JUDGE':
    from numba.pycc import CC
    cc = CC('my_module')
    cc.export('maximal_rectangle', signature)(maximal_rectangle)
    cc.compile()

from my_module import maximal_rectangle

A = np.array(read().split(), np.int64)[1:]

N = len(A)
L, R = maximal_rectangle(A)
coef = (np.arange(N) - L + 1) * (R - np.arange(N))
x = np.sum(coef * A)
print(x)

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 7)
 
input = sys.stdin.buffer.readline

class SegTree():
    
    def __init__(self, N, function, basement):
        self.n = N
        self.K = (self.n-1).bit_length()
        self.f = function
        self.b = basement
        self.seg = [basement]*(2**(self.K+1)+1)

    def update(self, k, value):
        X = 2**self.K
        k += X
        self.seg[k] = value
        while k:
            k = k >> 1
            self.seg[k] = self.f(self.seg[k << 1], self.seg[(k << 1) | 1])

    def query(self, L, R):
        num = 2**self.K
        L += num
        R += num
        vL = self.b
        vR = self.b
        while L < R:
            if L & 1:
                vL = self.f(vL, self.seg[L])
                L += 1
            if R & 1:
                R -= 1
                vR = self.f(self.seg[R], vR)
            L >>= 1
            R >>= 1
        return self.f(vL, vR)

    def find_max_index(self, L, R, X):
        
        return self.fMi(L, R, X, 1, 0, 2**self.K)

    def find_min_index(self, L, R, X):
        
        return self.fmi(L, R, X, 1, 0, 2**self.K)

    def fMi(self, a, b, x, k, l, r):
        if self.seg[k] > x or r <= a or b <= l:
            return -1
        else:
            if k >= 2**self.K:
                return k-2**self.K
            else:
                vr = self.fMi(a, b, x, (k << 1) | 1, (l + r) // 2, r)
                if vr != -1:
                    return vr
                return self.fMi(a, b, x, k << 1, l, (l + r) // 2)

    def fmi(self, a, b, x, k, l, r):
        if self.seg[k] > x or r <= a or b <= l:
            return -1
        else:
            if k >= 2**self.K:
                return k-2**self.K
            else:
                vl = self.fmi(a, b, x, k << 1, l, (l+r)//2)
                if vl != -1:
                    return vl
                return self.fmi(a, b, x, k << 1 | 1, (l+r)//2, r)

def main():
    N = int(input())
    A = list(map(int, input().split()))
    seg = SegTree(N, min, N+1)
    B = [0]*N
    for i, v in enumerate(A):
        B[i] = (i, A[i])
    B.sort(key=lambda x: x[1])
    ans = 0
    for index, v in B:
        seg.update(index, 1)
        left = seg.find_max_index(0, index, 1)
        right = seg.find_min_index(index+1, N, 1)
        if right == -1:
            right = N
        ans += v*(index-left)*(right-index)
    print(ans)
if __name__=="__main__":
    main()

Solution (Python):
n = int(input())
A = list(map(int,input().split()))

class Bit:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
  
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
  
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

ans = 0
L = Bit(n)
R = Bit(n)

B = [[A[i], i, n-i-1] for i in range(n)]
B.sort()
for i in range(n):
    
    ind = B[i][1]+1
    l = 0
    r = ind+1
    m = (l+r)//2
    lind = L.sum(ind)
    while r-l>1:
        if L.sum(m)< lind:
            l = m
        else:
            r = m
        m = (l+r)//2
    a = l
    L.add(ind+1, 1)
    

    ind = B[i][2]+1
    l = 0
    r = ind+1
    m = (l+r)//2
    rind = R.sum(ind)
    while r-l>1:
        if R.sum(m) < rind:
            l = m
        else:
            r = m
        m = (l+r)//2
    b = l
    R.add(ind+1, 1)

    ans += (i+1) * (B[i][1]+1 - a) * (n+1-b - (B[i][1]+1))
    


print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10000000)
MOD = 10 ** 9 + 7
INF = 10 ** 15

def main():
    N = int(input())
    A = list(enumerate(map(int,input().split())))
    A.sort(key = lambda x:-x[1])

    left = list(range(-1,N + 2))
    right = list(range(1,N + 4))
    ans = 0
    for i,a in A:
        L = left[i]
        R = right[i]
        ans += a*(i - L)*(R - i)
        left[R] = L
        right[L] = R
    print(ans)
if __name__ == '__main__':
    main()

Solution (Python):

import sys


buff_readline = sys.stdin.readline
readline = sys.stdin.readline

INF = 2**62-1


def read_int():
    return int(buff_readline())


def read_int_n():
    return list(map(int, buff_readline().split()))


def read_float():
    return float(buff_readline())


def read_float_n():
    return list(map(float, buff_readline().split()))


def read_str():
    return readline().strip()


def read_str_n():
    return readline().strip().split()


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.time()
        ret = f(*args, **kwargs)
        e = time.time()

        error_print(e - s, 'sec')
        return ret

    return wrap


class SegmentTree:
    def __init__(self, array, operator, identity_element):
        _len = len(array)
        self.__op = operator
        self.__size = 1 << (_len - 1).bit_length()
        self.__tree = [identity_element] * self.__size + \
            array + [identity_element] * (self.__size - _len)
        self.__ie = identity_element

        for i in range(self.__size - 1, 0, -1):
            self.__tree[i] = operator(
                self.__tree[i * 2], self.__tree[i * 2 + 1])

    def update(self, i, v):
        i += self.__size
        self.__tree[i] = v
        while i:
            i //= 2
            self.__tree[i] = self.__op(
                self.__tree[i * 2], self.__tree[i * 2 + 1])

    def query(self, l, r):
        """[l, r)
        """
        l += self.__size
        r += self.__size
        ret = self.__ie
        while l < r:
            if l & 1:
                ret = self.__op(ret, self.__tree[l])
                l += 1
            if r & 1:
                r -= 1
                ret = self.__op(ret, self.__tree[r])
            l //= 2
            r //= 2
        return ret


@mt
def slv(N, A):
    ai = [(a, i) for i, a in enumerate(A)]
    ai.sort()

    lst = SegmentTree([-1] * N, max, -1)
    rst = SegmentTree([N] * N, min, N)
    ans = 0
    for a, i in ai:
        l = lst.query(0, i)
        r = rst.query(i+1, N)
        ans += (i-l) * (r-i) * a
        lst.update(i, i)
        rst.update(i, i)
    return ans


def main():
    N = read_int()
    A = read_int_n()
    print(slv(N, A))


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.buffer.readline

def main():
	
	
	class SegmentTree:
		
		
		def __init__(self, size, default):
			self.size = 2**(size-1).bit_length()
			self.default = default
			self.seg = [default]*(2*self.size-1)

		
		def segfunc(self,x,y):
			return max(x,y)

		
		def update(self,k,x):
			k += self.size-1
			self.seg[k] = x
			while k:
				k = (k-1)//2
				self.seg[k] = self.segfunc(self.seg[2*k+1],self.seg[2*k+2])

		
		def query(self,p,q):
			if q <= p:
				return self.default
			p += self.size-1;q += self.size-2
			ret = self.default
			while q-p > 1:
				if p&1 == 0:
					ret = self.segfunc(ret,self.seg[p])
				if q&1 == 1:
					ret = self.segfunc(ret,self.seg[q])
					q -= 1
				p = p//2
				q = (q-1)//2
			ret = self.segfunc(self.segfunc(ret,self.seg[p]),self.seg[q])
			return ret

		
		def seg_print(self):
			print(self.seg)
		
	N = int(input())
	a = list(map(int,input().split()))
	ans=[i+1 for i in range(N)]
	left_seg = SegmentTree(N, 0)
	for i, num in enumerate(a):
	    ans[num-1] *= i + 1 - left_seg.query(0,num)
	    left_seg.update(num-1, i+1)
	right_seg = SegmentTree(N, 0)
	for i, num in enumerate(a[::-1]):
	    ans[num-1] *= i + 1 - right_seg.query(0,num)
	    right_seg.update(num-1, i+1)
	
	print(sum(ans))

if __name__ == "__main__":
	main()

Solution (Python):
import sys
input = sys.stdin.buffer.readline

def main():
	
	class BinaryIndexedTree:
		
		
		def __init__(self, size, default):
			self.size = size
			self.default = default
			self.BIT = [default]*(self.size+1)

		
		def BIT_segfunc(self, x, y):
			return max(x, y)

		def BIT_query(self, idx):
			ret = self.default
			while idx > 0:
				ret = self.BIT_segfunc(ret, self.BIT[idx])
				idx -= idx&(-idx)
			return ret

		
		def BIT_update(self, idx, x):
			while idx <= self.size:
				self.BIT[idx] = self.BIT_segfunc(self.BIT[idx], x)
				idx += idx&(-idx)
			return

		def BIT_range(self, x, y):
			return self.BIT_query(y)-self.BIT_query(x)

		
		def BIT_print(self):
			print(self.BIT)
		
	N = int(input())
	a = list(map(int,input().split()))
	l = [0]*N;r = [0]*N
	left_bit = BinaryIndexedTree(N, 0)
	for i, num in enumerate(a):
	    l[num-1] = i + 1 - left_bit.BIT_query(num)
	    left_bit.BIT_update(num, i+1)
	right_bit = BinaryIndexedTree(N, 0)
	for i, num in enumerate(a[::-1]):
	    r[num-1] = i + 1 - right_bit.BIT_query(num)
	    right_bit.BIT_update(num, i+1)
	
	print(sum(l[i]*r[i]*(i+1) for i in range(N)))

if __name__ == "__main__":
	main()