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):
from bisect import*
class SquareSkipList:
    def __init__(self,values=None,sorted_=False,square=1000,seed=42):
        inf=float("inf")
        self.square=square
        if values is None:
            self.rand_y=seed
            self.layer1=[inf]
            self.layer0=[[]]
        else:
            self.layer1=layer1=[]
            self.layer0=layer0=[]
            if not sorted_:values.sort()
            y=seed
            l0=[]
            for v in values:
                y^=(y&0x7ffff)<<13
                y^=y>>17
                y^=(y&0x7ffffff)<<5
                if y%square<1:
                    layer0.append(l0)
                    l0=[]
                    layer1.append(v)
                else:l0.append(v)
            layer1.append(inf)
            layer0.append(l0)
            self.rand_y=y
    def add(self,x):
        y=self.rand_y
        y^=(y&0x7ffff)<<13
        y^=y>>17
        y^=(y&0x7ffffff)<<5
        self.rand_y=y
        if y%self.square<1:
            layer1,layer0=self.layer1,self.layer0
            idx1=bisect(layer1,x)
            layer1.insert(idx1,x)
            layer0_idx1=layer0[idx1]
            idx0=bisect(layer0_idx1,x)
            layer0.insert(idx1+1,layer0_idx1[idx0:])
            del layer0_idx1[idx0:]
        else:
            idx1=bisect(self.layer1,x)
            insort(self.layer0[idx1],x)
    def remove(self,x):
        idx1=bisect_left(self.layer1,x)
        layer0_idx1=self.layer0[idx1]
        idx0=bisect_left(layer0_idx1,x)
        if idx0==len(layer0_idx1):
            del self.layer1[idx1]
            self.layer0[idx1]+=self.layer0.pop(idx1+1)
        else:del layer0_idx1[idx0]
    def search_higher_equal(self,x):
        idx1=bisect_left(self.layer1,x)
        layer0_idx1=self.layer0[idx1]
        idx0=bisect_left(layer0_idx1,x)
        if idx0==len(layer0_idx1):return self.layer1[idx1]
        return layer0_idx1[idx0]
    def search_higher(self,x):
        idx1=bisect(self.layer1,x)
        layer0_idx1=self.layer0[idx1]
        idx0=bisect_right(layer0_idx1,x)
        if idx0==len(layer0_idx1):return self.layer1[idx1]
        return layer0_idx1[idx0]
    def search_lower(self,x):
        idx1=bisect_left(self.layer1,x)
        layer0_idx1=self.layer0[idx1]
        idx0=bisect_left(layer0_idx1,x)
        if idx0==0:return self.layer1[idx1-1]
        return layer0_idx1[idx0-1]
    def pop(self, idx):
        layer0=self.layer0
        s=-1
        for i,l0 in enumerate(layer0):
            s+=len(l0)+1
            if s>=idx:break
        if s==idx:
            layer0[i]+=layer0.pop(i+1)
            return self.layer1.pop(i)
        else:return layer0[i].pop(idx-s)
    def print(self):
        print(self.layer1)
        print(self.layer0)
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=SquareSkipList()
    t.add(0)
    t.add(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.add(v)
    print(c)
main()

Solution (Python):
from operator import itemgetter
import sys
input = sys.stdin.readline




class BITbisect():
    def __init__(self, max_X):
        self.max_X = max_X + 1
        self.bit = [0]*(self.max_X+1)

    
    def add(self, x, a):
        while x <= self.max_X:
            self.bit[x] += a
            x += x & -x

    def insert(self, x):
        self.add(x, 1)

    def delete(self, x):
        self.add(x, -1)

    
    def query_sum(self, x):
        s = 0
        while x > 0:
            s += self.bit[x]
            x -= x & -x
        return s

    def exist(self, x):
        if self.query_sum(x) - self.query_sum(x-1) > 0:
            return True
        return False
    
    def count(self, x):
        return self.query_sum(x) - self.query_sum(x-1)

    
    
    def upper(self, x):
        qx = self.query_sum(x) + 1
        if qx > self.query_sum(self.max_X):
            return False
        l = 0
        r = self.max_X
        while l < r:
            m = (l+r)//2
            if self.query_sum(m) < qx:
                if l == m:
                    return r
                l = m
            else:
                r = m
        if m == self.max_X:
            return False
        return m

    
    
    def lower(self, x):
        qx = self.query_sum(x)
        if qx == 0:
            return False
        l = 0
        r = self.max_X
        while l < r:
            m = (l+r)//2
            if self.query_sum(m) < qx:
                if l == m:
                    return r
                l = m
            else:
                r = m
        return m

    
    def display(self):
        print('inside BIT:', end=' ')
        for x in range(1, self.max_X):
            if bit.exist(x):
                c = bit.count(x)
                for _ in range(c):
                    print(x, end=' ')
        print()


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

B = []
for i, a in enumerate(A):
    B.append((i+1, a))
B.sort(key=itemgetter(1))

bit = BITbisect(N)

ans = 0
for i, a in B:
    l = bit.lower(i)
    r = bit.upper(i)
    if l is False:
        l = 0
    if r is False:
        r = N+1
    ans += (i-l)*(r-i)*a
    bit.insert(i)
print(ans)

Solution (Python):
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

    
    def bisect_plus(self, i, t):
        L = i
        R = self.size
        R_prev = R
        sum_i = self.sum(i)
        while True:
            range_sum = self.sum(R) - sum_i
            if range_sum < t:
                if R == self.size:
                    return self.size + 1
                L, R = R, R_prev
            else:
                R_prev = R
                R = (L + R + 1) // 2
                if R == R_prev:
                    return R

    
    def bisect_minus(self, i, t):
        L = 1
        R = i
        L_prev = L
        sum_i = self.sum(i - 1)
        while True:
            range_sum = sum_i - self.sum(L - 1)
            if range_sum < t:
                if L == 1:
                    return 0
                L, R = L_prev, L
            else:
                L_prev = L
                L = (L + R) // 2
                if L == L_prev:
                    return L


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

idx = [0] * (N+1)
for i in range(N):
    idx[a[i]] = i+1

bit = Bit(N)
ans = 0
for i in range(1, N+1):
    p = idx[i]
    bit.add(p, 1)
    L = bit.bisect_minus(p, 1)
    R = bit.bisect_plus(p, 1)
    ans += (((R-L) * (R-L-1)) // 2 - ((p-L) * (p-L-1)) // 2 - ((R-p) * (R-p-1)) // 2) * i

print(ans)

Solution (Python):



import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(1000000000)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

n = I()
a = LI()
lst = [0 for i in range(n+1)]
for i in range(n):
    lst[a[i]] = i

l = [0]*n
r = [0]*n
ans = 0
for i in range(1,n+1)[::-1]:
    x = lst[i]
    if x + 1 < n and a[x+1] > i:
        R = r[x+1]
    else:
        R = x
    if x - 1 >= 0 and a[x-1] > i:
        L = l[x-1]
    else:
        L = x
    l[R] = L
    r[L] = R
    ans += (x - L + 1)*(R - x + 1)*i
print(ans)

Solution (Python):
N = int(input())
a = list(map(int, input().split()))
E = [(v, i + 1) for i, v in enumerate(a)]
E.sort(reverse = True)
L = [0] + [i for i in range(N + 1)]
R = [i + 1 for i in range(N + 1)] + [N + 1]
res = 0
for v, i in E:
  l = L[i]
  r = R[i]
  L[r], R[l] = l, r
  res += v * (i - l) * (r - i)
print(res)

Solution (Python):
class Multiset:
    def __init__(self, N):
        self.N = N
        self.tree = [0] * (N + 1)
        self.bisect_K = [1 << k for k in reversed(range(N.bit_length()))]

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

    def __str__(self):
        return "BIT: [{}]".format(
            ", ".join(str(self.sum(i + 1) - self.sum(i))
                      for i in range(self.N))
        )

    def bisect(self, w):
        if w <= 0:
            return 0
        bit, N = self.tree, self.N
        i = 0
        for k in self.bisect_K:
            ni = i + k
            if ni <= N and bit[ni] < w:
                w -= bit[ni]
                i = ni
        return i + 1

    def insert(self, i):
        while i <= self.N:
            self.tree[i] += 1
            i += i & -i

    def erase(self, i):
        while i <= self.N:
            self.tree[i] -= 1
            i += i & -i

    def lower_bound(self, x):
        return self.bisect(self.sum(x))

    def upper_bound(self, x):
        return self.bisect(self.sum(x) + 1)

    def size(self):
        return self.sum(self.N)


def main():

    N, *A = map(int, open(0).read().split())
    B = {a: i for i, a in enumerate(A, 2)}

    ms = Multiset(N + 2)
    ms.insert(1)
    ms.insert(N + 2)

    ans = 0
    for i in range(1, N + 1):
        b = B[i]
        ms.insert(b)
        l = ms.lower_bound(b - 1)
        r = ms.upper_bound(b)
        ans += i * (b - l) * (r - b)

    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
class UnionFind():
    def __init__(self,size):
        self.table=[-1]*size
    def root(self,x):
        while self.table[x]>=0:
            x=self.table[x]
        return x
    def unite(self,x,y):
        s1=self.root(x)
        s2=self.root(y)
        if s1!=s2:
            if self.table[s1]>self.table[s2]:
                s1,s2=s2,s1
            self.table[s1]+=self.table[s2]
            self.table[s2]=s1
        return
    def same(self,x,y):
        return self.root(x)==self.root(y)
    def size(self,x):
        return -self.table[self.root(x)]
n,*a=map(int,open(0).read().split())
u=UnionFind(n)
b=[0]*n
for i,t in enumerate(a):b[t-1]=i
c=0
for k in b[::-1]:
    l=r=1
    if k>0 and a[k-1]>a[k]:
        l+=u.size(k-1)
        u.unite(k-1,k)
    if k+1<n and a[k+1]>a[k]:
        r+=u.size(k+1)
        u.unite(k+1,k)
    c+=l*r*a[k]
print(c)

Solution (Python):
from bisect import*
class SqrtSet:
    def __init__(self,block_limit=201):
        self.key=[]
        self.child=[[]]
        self.block_limit=block_limit
    def search_lower(self,key):
        if not key:return None
        ret=None
        i=bisect_left(self.key,key)
        if i:ret=self.key[i-1]
        block=self.child[i]
        i=bisect_left(block,key)
        if i:ret=block[i-1]
        return ret
    def search_higher(self,key):
        if not key:return None
        ret=None
        i=bisect(self.key,key)
        if i<len(self.key):ret=self.key[i]
        block=self.child[i]
        i=bisect(block,key)
        if i<len(block):ret=block[i]
        return ret
    def insert(self,key):
        i=bisect(self.key,key)
        block=self.child[i]
        insort(block,key)
        if len(block)==self.block_limit:
            sep=self.block_limit//2
            self.key.insert(i,block[sep])
            self.child.insert(i+1,block[sep+1:])
            self.child[i]=block[:sep]
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=SqrtSet()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

Solution (Python):
from bisect import*
class SqrtSet:
    def __init__(self,block_limit=201):
        self.key=[]
        self.child=[[]]
        self.block_limit=block_limit
    def search_lower(self,key):
        if not key:return None
        ret=None
        i=bisect_left(self.key,key)
        if i:ret=self.key[i-1]
        block=self.child[i]
        i=bisect_left(block,key)
        if i:ret=block[i-1]
        return ret
    def search_higher(self,key):
        if not key:return None
        ret=None
        i=bisect(self.key,key)
        if i<len(self.key):ret=self.key[i]
        block=self.child[i]
        i=bisect(block,key)
        if i<len(block):ret=block[i]
        return ret
    def insert(self,key):
        i=bisect(self.key,key)
        block=self.child[i]
        insort(block,key)
        if len(block)==self.block_limit:
            sep=self.block_limit//2
            self.key.insert(i,block[sep])
            self.child.insert(i+1,block[sep+1:])
            self.child[i]=block[:sep]
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=SqrtSet()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

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

Solution (Python):
from bisect import*
class BTreeNode:
    def __init__(self):self.key,self.child=[],[]
class BTree:
    def __init__(self):self.root=BTreeNode()
    def search_higher(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect(ptr.key,key)
            if i!=len(ptr.key):ret=ptr.key[i]
            ptr=ptr.child[i]
        i=bisect(ptr.key,key)
        if i!=len(ptr.key):ret=ptr.key[i]
        return ret
    def search_lower(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect_left(ptr.key,key)
            if i:ret=ptr.key[i-1]
            ptr=ptr.child[i]
        i=bisect_left(ptr.key,key)
        if i:ret=ptr.key[i-1]
        return ret
    def insert(self,key):
        def insert_rec(ptr):
            b_size=256
            if not ptr.child:
                insort(ptr.key,key)
                if len(ptr.key)==b_size*2-1:
                    ret=BTreeNode()
                    ret.key=ptr.key[:b_size]
                    ptr.key=ptr.key[b_size:]
                    return ret
            else:
                i=bisect(ptr.key,key)
                tmp=insert_rec(ptr.child[i])
                if tmp:
                    ptr.key.insert(i,tmp.key.pop())
                    ptr.child.insert(i,tmp)
                    if len(ptr.child)==b_size*2:
                        ret=BTreeNode()
                        ret.child=ptr.child[:b_size]
                        ptr.child=ptr.child[b_size:]
                        ret.key=ptr.key[:b_size]
                        ptr.key=ptr.key[b_size:]
                        return ret
        tmp=insert_rec(self.root)
        if tmp:
            root=BTreeNode()
            root.key=[tmp.key.pop()]
            root.child=[tmp,self.root]
            self.root=root
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=BTree()
    insert,search_higher,search_lower=t.insert,t.search_higher,t.search_lower
    insert(0)
    insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(search_higher(v)-v)*(v-search_lower(v))*i
        insert(v)
    print(c)
main()

Solution (Python):
from bisect import*
class BTreeNode:
    def __init__(self):self.key,self.child=[],[]
class BTree:
    def __init__(self):self.root=BTreeNode()
    def search_higher(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect(ptr.key,key)
            if i!=len(ptr.key):ret=ptr.key[i]
            ptr=ptr.child[i]
        i=bisect(ptr.key,key)
        if i!=len(ptr.key):ret=ptr.key[i]
        return ret
    def search_lower(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect_left(ptr.key,key)
            if i:ret=ptr.key[i-1]
            ptr=ptr.child[i]
        i=bisect_left(ptr.key,key)
        if i:ret=ptr.key[i-1]
        return ret
    def insert(self,key):
        def insert_rec(ptr):
            b_size=256
            if not ptr.child:
                insort(ptr.key,key)
                if len(ptr.key)==b_size*2-1:
                    ret=BTreeNode()
                    ret.key=ptr.key[:b_size]
                    ptr.key=ptr.key[b_size:]
                    return ret
            else:
                i=bisect(ptr.key,key)
                tmp=insert_rec(ptr.child[i])
                if tmp:
                    ptr.key.insert(i,tmp.key.pop())
                    ptr.child.insert(i,tmp)
                    if len(ptr.child)==b_size*2:
                        ret=BTreeNode()
                        ret.child=ptr.child[:b_size]
                        ptr.child=ptr.child[b_size:]
                        ret.key=ptr.key[:b_size]
                        ptr.key=ptr.key[b_size:]
                        return ret
        tmp=insert_rec(self.root)
        if tmp:
            root=BTreeNode()
            root.key=[tmp.key.pop()]
            root.child=[tmp,self.root]
            self.root=root
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=BTree()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

Solution (Python):
from bisect import*
class BTreeNode:
    def __init__(self):self.key,self.child=[],[]
root=BTreeNode()
def main():
    def search_higher(key):
        ptr=root
        ret=None
        while ptr.child:
            i=bisect(ptr.key,key)
            if i!=len(ptr.key):ret=ptr.key[i]
            ptr=ptr.child[i]
        i=bisect(ptr.key,key)
        if i!=len(ptr.key):ret=ptr.key[i]
        return ret
    def search_lower(key):
        ptr=root
        ret=None
        while ptr.child:
            i=bisect_left(ptr.key,key)
            if i:ret=ptr.key[i-1]
            ptr=ptr.child[i]
        i=bisect_left(ptr.key,key)
        if i:ret=ptr.key[i-1]
        return ret
    def insert_rec(ptr,key):
        b_size=512
        if not ptr.child:
            insort(ptr.key,key)
            if len(ptr.key)==b_size*2-1:
                ret=BTreeNode()
                ret.key=ptr.key[:b_size]
                ptr.key=ptr.key[b_size:]
                return ret
        else:
            i=bisect(ptr.key,key)
            tmp=insert_rec(ptr.child[i],key)
            if tmp:
                ptr.key.insert(i,tmp.key.pop())
                ptr.child.insert(i,tmp)
                if len(ptr.child)==b_size*2:
                    ret=BTreeNode()
                    ret.child=ptr.child[:b_size]
                    ptr.child=ptr.child[b_size:]
                    ret.key=ptr.key[:b_size]
                    ptr.key=ptr.key[b_size:]
                    return ret
    def insert(key):
        global root
        tmp=insert_rec(root,key)
        if tmp:
            p=BTreeNode()
            p.key=[tmp.key.pop()]
            p.child=[tmp,root]
            root=p
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    insert(0)
    insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(search_higher(v)-v)*(v-search_lower(v))*i
        insert(v)
    print(c)
main()

Solution (Python):
from bisect import*
class BTreeNode:
    def __init__(self):self.key,self.child=[],[]
class BTree:
    def __init__(self):self.root=BTreeNode()
    def search_higher(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect(ptr.key,key)
            if i!=len(ptr.key):ret=ptr.key[i]
            ptr=ptr.child[i]
        i=bisect(ptr.key,key)
        if i!=len(ptr.key):ret=ptr.key[i]
        return ret
    def search_lower(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect_left(ptr.key,key)
            if i:ret=ptr.key[i-1]
            ptr=ptr.child[i]
        i=bisect_left(ptr.key,key)
        if i:ret=ptr.key[i-1]
        return ret
    def insert(self,key):
        def insert_rec(ptr):
            b_size=512
            if not ptr.child:
                insort(ptr.key,key)
                if len(ptr.key)==b_size*2-1:
                    ret=BTreeNode()
                    ret.key=ptr.key[:b_size]
                    ptr.key=ptr.key[b_size:]
                    return ret
            else:
                i=bisect(ptr.key,key)
                tmp=insert_rec(ptr.child[i])
                if tmp:
                    ptr.key.insert(i,tmp.key.pop())
                    ptr.child.insert(i,tmp)
                    if len(ptr.child)==b_size*2:
                        ret=BTreeNode()
                        ret.child=ptr.child[:b_size]
                        ptr.child=ptr.child[b_size:]
                        ret.key=ptr.key[:b_size]
                        ptr.key=ptr.key[b_size:]
                        return ret
        tmp=insert_rec(self.root)
        if tmp:
            root=BTreeNode()
            root.key=[tmp.key.pop()]
            root.child=[tmp,self.root]
            self.root=root
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=BTree()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

Solution (Python):
from bisect import*
class BTreeNode:
    def __init__(self):self.key,self.child=[],[]
class BTree:
    def __init__(self):self.root=BTreeNode()
    def search_higher(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect(ptr.key,key)
            if i!=len(ptr.key):ret=ptr.key[i]
            ptr=ptr.child[i]
        i=bisect(ptr.key,key)
        if i!=len(ptr.key):ret=ptr.key[i]
        return ret
    def search_lower(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect_left(ptr.key,key)
            if i:ret=ptr.key[i-1]
            ptr=ptr.child[i]
        i=bisect_left(ptr.key,key)
        if i:ret=ptr.key[i-1]
        return ret
    def insert(self,key):
        def insert_rec(ptr,key):
            b_size=512
            if not ptr.child:
                insort(ptr.key,key)
                if len(ptr.key)==b_size*2-1:
                    ret=BTreeNode()
                    ret.key=ptr.key[:b_size]
                    ptr.key=ptr.key[b_size:]
                    return ret
            else:
                i=bisect(ptr.key,key)
                tmp=insert_rec(ptr.child[i],key)
                if tmp:
                    ptr.key.insert(i,tmp.key.pop())
                    ptr.child.insert(i,tmp)
                    if len(ptr.child)==b_size*2:
                        ret=BTreeNode()
                        ret.child=ptr.child[:b_size]
                        ptr.child=ptr.child[b_size:]
                        ret.key=ptr.key[:b_size]
                        ptr.key=ptr.key[b_size:]
                        return ret
        tmp=insert_rec(self.root,key)
        if tmp:
            root=BTreeNode()
            root.key=[tmp.key.pop()]
            root.child=[tmp,self.root]
            self.root=root
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=BTree()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

Solution (Python):
from bisect import*
class BTreeNode:
    def __init__(self):self.key,self.child=[],[]
class BTree:
    def __init__(self):self.root=BTreeNode()
    def search_higher(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect(ptr.key,key)
            if i!=len(ptr.key):ret=ptr.key[i]
            ptr=ptr.child[i]
        i=bisect(ptr.key,key)
        if i!=len(ptr.key):ret=ptr.key[i]
        return ret
    def search_lower(self,key):
        ptr=self.root
        ret=None
        while ptr.child:
            i=bisect_left(ptr.key,key)
            if i:ret=ptr.key[i-1]
            ptr=ptr.child[i]
        i=bisect_left(ptr.key,key)
        if i:ret=ptr.key[i-1]
        return ret
    def insert(self,key):
        def insert_rec(ptr,key):
            b_size=512
            if not ptr.child:
                insort(ptr.key,key)
                if len(ptr.key)==b_size*2-1:
                    ret=BTreeNode()
                    ret.key=ptr.key[:b_size]
                    ptr.key=ptr.key[b_size:]
                    return ret
            else:
                i=bisect(ptr.key,key)
                tmp=insert_rec(ptr.child[i],key)
                if tmp:
                    ptr.key.insert(i,tmp.key.pop())
                    ptr.child.insert(i,tmp)
                    if len(ptr.child)==b_size*2:
                        ret=BTreeNode()
                        ret.child=ptr.child[:b_size]
                        ptr.child=ptr.child[b_size:]
                        ret.key=ptr.key[:b_size]
                        ptr.key=ptr.key[b_size:]
                        return ret
                return None
        tmp=insert_rec(self.root,key)
        if tmp:
            root=BTreeNode()
            root.key=[tmp.key.pop()]
            root.child=[tmp,self.root]
            self.root=root
def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=BTree()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

Solution (Python):
import bisect


class BTreeNode:
    def __init__(self):
        self.key = []
        self.child = []


class BTree:
    def __init__(self):
        self.root = BTreeNode()

    def search_higher(self, key):
        ptr = self.root
        ret = None
        while ptr.child:
            i = bisect.bisect_right(ptr.key, key)
            if i != len(ptr.key):
                ret = ptr.key[i]
            ptr = ptr.child[i]
        i = bisect.bisect_right(ptr.key, key)
        if i != len(ptr.key):
            ret = ptr.key[i]
        return ret

    def search_lower(self, key):
        ptr = self.root
        ret = None
        while ptr.child:
            i = bisect.bisect_left(ptr.key, key)
            if i != 0:
                ret = ptr.key[i - 1]
            ptr = ptr.child[i]
        i = bisect.bisect_left(ptr.key, key)
        if i != 0:
            ret = ptr.key[i - 1]
        return ret

    def insert(self, key):
        def insert_rec(ptr):
            b_size = 512
            if not ptr.child:
                bisect.insort(ptr.key, key)
                if len(ptr.key) == b_size * 2 - 1:
                        ret = BTreeNode()
                        ret.key = ptr.key[:b_size]
                        ptr.key = ptr.key[b_size:]
                        return ret
            else:
                i = bisect.bisect(ptr.key, key)
                temp = insert_rec(ptr.child[i])
                if temp is not None:
                    ptr.key.insert(i, temp.key.pop(-1))
                    ptr.child.insert(i, temp)
                    if len(ptr.child) == b_size * 2:
                        ret = BTreeNode()
                        ret.child = ptr.child[:b_size]
                        ptr.child = ptr.child[b_size:]
                        ret.key = ptr.key[:b_size]
                        ptr.key = ptr.key[b_size:]
                        return ret
            return None
        temp = insert_rec(self.root)
        if temp is not None:
            root = BTreeNode()
            root.key = [temp.key.pop(-1)]
            root.child = [temp, self.root]
            self.root = root

    def dump(self):
        def dump_rec(ptr, dep):
            for _ in range(0, dep):
                print("  ", end="")
            print(ptr.key)
            for c in ptr.child:
                dump_rec(c, dep + 1)
        dump_rec(self.root, 0)
        print("")


def main():
    n,*a=map(int,open(0).read().split())
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=BTree()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

Solution (Python):

ans=0
n=int(input())
A=list(map(int,input().split()))
B=[0]*(n+1)
for i in range(n):
    B[A[i]]=i+1
LL=[int(i) for i in range(n+2)]
RR=[int(i) for i in range(n+2)]
for i in range(n,0,-1):
    l=LL[B[i]]
    r=RR[B[i]]
    ans+=(B[i]-l+1)*(r-B[i]+1)*i
    LL[r+1]=l
    RR[l-1]=r
print(ans)

Solution (Python):

ans=0
n=int(input())
A=list(map(int,input().split()))
B=[0]*(n+1)
for i in range(n):
    B[A[i]]=i+1
LL=[int(i) for i in range(n+2)]
RR=[int(i) for i in range(n+2)]
for i in range(n,0,-1):
    l=LL[B[i]]
    r=RR[B[i]]
    ans+=(B[i]-l+1)*(r-B[i]+1)*i
    LL[r+1]=l
    RR[l-1]=r
print(ans)

Solution (Python):

class UnionFind:
    __slots__ = ['id','sz']

    def __init__(self, n):
        self.id = [-1] * n

    def root(self, x):
        if self.id[x] < 0:
            return x
        else:
            self.id[x] = self.root(self.id[x])
            return self.id[x]

    def find(self, x, y):
        return uf.root(x) == uf.root(y)

    def union(self, x, y):
        s1, s2 = self.root(x), self.root(y)
        if s1 != s2:
            if self.id[s1] <= self.id[s2]:
                self.id[s1] += self.id[s2]
                self.id[s2] = s1
            else:
                self.id[s2] += self.id[s1]
                self.id[s1] = s2
            return True
        return False

n = int(input())
a = list(map(int,input().split()))
uf = UnionFind(n)
ans=0
data=[0]*n
b=[0]*(n+1)
for i in range(n):
    b[a[i]]=i
for i in range(n,0,-1):
    r,l=0,0
    data[b[i]]=i
    if b[i]+1 <= n-1:
        if data[b[i]+1]>0:
            uf.union(b[i],b[i]+1)
    r=-uf.id[uf.root(b[i])]

    if b[i]-1>=0 and data[b[i]-1]>0:
        uf.union(b[i],b[i]-1)
    l=1-uf.id[uf.root(b[i])]-r
    ans+=(r*l)*i
print(ans)

Solution (Python):
N = int(input())
a = list(map(int,input().split()))
l = [i for i in range(N)]
r = [i for i in range(N)]

b = [0] * N
for i in range(N):
    b[a[i]-1] = i

ans = 0
for i in range(N-1,-1,-1):
    m = b[i]
    x,y = l[m],r[m]
    ans += (i+1)*(m-x+1)*(y-m+1)
    l[min(y+1,N-1)] = x
    r[max(x-1,0)] = y
print(ans)

Solution (Python):
N = int(input())
A = [int(x) for x in input().split()]
B = [0] * (N + 1)
for i in range(N):
  B[A[i]] = i + 1
L = list(range(N + 2))
R = list(range(N + 2))
cnt = 0
for i in range(N, 0, -1):
  l = L[B[i]]
  r = R[B[i]]
  cnt += i * (B[i] - l + 1) * (r - B[i] + 1)
  L[r + 1] = l
  R[l - 1] = r
print(cnt)