Problem:


Score: 500 points

Problem Statement

Given is a permutation P of \{1, 2, \ldots, N\}.

For a pair (L, R) (1 \le L \lt R \le N), let X_{L, R} be the second largest value among P_L, P_{L+1}, \ldots, P_R.

Find \displaystyle \sum_{L=1}^{N-1} \sum_{R=L+1}^{N} X_{L,R}.

Constraints

 2 \le N \le 10^5 

 1 \le P_i \le N 

 P_i \neq P_j  (i \neq j)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
P_1 P_2 \ldots P_N

Output

Print \displaystyle \sum_{L=1}^{N-1} \sum_{R=L+1}^{N} X_{L,R}.

Sample Input 1

3
2 3 1

Sample Output 1

5

X_{1, 2} = 2, X_{1, 3} = 2, and X_{2, 3} = 1, so the sum is 2 + 2 + 1 = 5.

Sample Input 2

5
1 2 3 4 5

Sample Output 2

30

Sample Input 3

8
8 2 7 3 4 5 6 1

Sample Output 3

136



Sample input:
3
2 3 1


Sample output:
5

Submission status: Time Limit Exceeded

Solution code:
import bisect

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

# index list
lst = [0] * (N + 1)
for i in range(N):
    lst[P[i]] = i

finished = [-1, -1, lst[N], N, N] # index set
#print(finished)
ans = 0
for i in range(N - 1, 0, -1):
    idx = lst[i]
    idx2 = bisect.bisect_left(finished, idx)
    bisect.insort_left(finished, idx)
    #print(finished)
    x = finished[idx2 - 1]
    y = finished[idx2 + 1]
    z = finished[idx2 + 2]
    w = finished[idx2 - 2]
    #print('When P_i = {}, w={}, x={}, y={}, z={}'.format(i,w,x,y,z))

    C = (x - w) * (y - idx) + (idx - x) * (z - y)
    ans += i * C
    #print('ans = {}'.format(ans))

print(ans)

Submission status: Time Limit Exceeded

Solution code:
import bisect
import numpy as np

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

max_idx = np.argmax(np.array(P))
finished = [-1, -1, max_idx, N, N] # index set
#print(finished)

ans = 0
for i in range(N - 1, 0, -1):
    idx = np.where(np.array(P) == i)[0][0]
    idx2 = bisect.bisect_left(finished, idx)
    bisect.insort_left(finished, idx)
    #print(finished)
    x = finished[idx2 - 1]
    y = finished[idx2 + 1]
    z = finished[idx2 + 2]
    w = finished[idx2 - 2]
    #print('When P_i = {}, w={}, x={}, y={}, z={}'.format(i,w,x,y,z))

    C = (x - w) * (y - idx) + (idx - x) * (z - y)
    ans += i * C
    #print('ans = {}'.format(ans))

print(ans)

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-
import sys
from bisect import bisect_left, bisect_right
from operator import itemgetter
from fractions import gcd
from math import ceil, floor, sqrt
from copy import deepcopy
from collections import Counter, deque
import heapq
from functools import reduce
from random import shuffle
sys.setrecursionlimit(200000)
# local only
if not __debug__:
    fin = open('text.txt', 'r')
    sys.stdin = fin
# local only
input = sys.stdin.readline
def ii(): return int(input())
def mi(): return map(int, input().rstrip().split())
def lmi(): return list(map(int, input().rstrip().split()))
def li(): return list(input().rstrip())
def debug(*args, sep=" ", end="\n"): print("debug:", *args, file=sys.stderr, sep=sep, end=end) if not __debug__ else None
def exit(*arg): print(*arg); sys.exit()
# template

# BEGIN CUT HERE
class Avltree:
    """
    AVL木

    Methods
    -------
        search(x: int) -> Union(int)
            ◯.data == x のものが存在するある場合それを出力、ない場合 None を返す
        insert(x: int) -> None
            ◯.data == x がない場合 ◯.data == x なる頂点を作る。ある場合はなにもしない（上書きしない）
        y.to_s() -> int
            頂点yのdataを返す
        y.left_s() -> Union(int, key=None)
            頂点yのleftを返す(ない場合は key)
        search_lower(x: int, key_lower) -> int
            ○.data が x より小さいものの中で最も大きいものを出力、ない場合 key_lower を返す
        search_higher(x:int , key_higher) -> int
            ○.data が x より大きいものの中で最も小さいものを出力、ない場合 key_higher を返す
    """

    def __init__(self, key=None):
        self.key = key
        self.left = None
        self.right = None
        self.balance = 0

    def search(self, key):
        if self.key is None:
            return None
        node = self
        while node is not None:
            if node.key == key:
                return node  # node.key == keyの場合
            if node.key > key:
                node = node.left
            if node.key < key:
                node = node.right
        return None

    def search_lower(self, key, key_lower):
        node = self
        if node.key is None:
            return key_lower
        ans = key_lower
        while node is not None:
            if node.key < key:
                ans = max(ans, node.key)
                node = node.right
            elif node.key >= key:
                node = node.left
        return ans

    def search_higher(self, key, key_higher):
        node = self
        if node.key is None:
            return key_higher
        ans = key_higher
        while node is not None:
            if node.key > key:
                ans = min(ans, node.key)
                node = node.left
            elif node.key <= key:
                node = node.right
        return ans


    def end_lower(self, end_lower_key):
        node = self
        while node.left is not None:
            node = node.left
        return node.key

    def end_higher(self, end_higher_key):
        node = self
        while node.right is not None:
            node = node.right
        return node.key


    def DoubleRightRotation(self):
        tl = self.left
        self.left = tl.right.right
        tl.right.right = self  # selfはそのノード
        tlr = tl.right
        tl.right = tlr.left
        tlr.left = tl
        if tlr.balance == -1:
            tlr.right.balance = 1
            tlr.left.balance = 0
        elif tlr.balance == 1:
            tlr.right.balance = 0
            tlr.left.balance = -1
        elif tlr.balance == 0:
            tlr.right.balance = 0
            tlr.left.balance = 0
        tlr.balance = 0
        return tlr
    def DoubleLeftRotation(self):
        tr = self.right
        self.right = tr.left.left
        tr.left.left = self
        trl = tr.left
        tr.left = trl.right
        trl.right = tr
        if trl.balance == 1:
            trl.left.balance = -1
            trl.right.balance = 0
        elif trl.balance == -1:
            trl.left.balance = 0
            trl.right.balance = 1
        elif trl.balance == 0:
            trl.left.balance = 0
            trl.right.balance = 0
        trl.balance = 0
        return trl
    def SingleLeftRotation(self):
        tr = self.right
        tr.balance = 0
        self.balance = 0
        self.right = tr.left
        tr.left = self
        return tr
    def SingleRightRotation(self):
        tl = self.left
        tl.balance = 0
        self.balance = 0
        self.left = tl.right
        tl.right = self
        return tl
    def replace(self, p, v):  # 親ノードpの下にある自分(self)をvに置き換える。
        if p.left == self:
            p.left = v
        else:
            p.right = v
    def insert(self, key):  # rootでのみ呼ばれる挿入
        if self.key is None:  # rootを含むrotationはしないことにする。
            self.key = key
            return self
        if key < self.key:
            if self.left is None:
                self.left = Avltree(key)
            else:
                self.left.insertx(self, key)
        elif key > self.key:
            if self.right is None:
                self.right = Avltree(key)
            else:
                self.right.insertx(self, key)
        else:  # key == self.key:
            pass  # do not overwrite
    def insertx(self, p, key):  # replaceを呼ぶために一つ上の親を持っているinsert
        if self.key > key:
            if self.left is None:
                self.left = Avltree(key)
            else:
                if not self.left.insertx(self, key):  # 左の木が生長しなければ、
                    return False  # 成長しない
            if self.balance == 1:
                self.balance = 0
                return False
            elif self.balance == 0:
                self.balance = -1
                return True  # 成長した
            elif self.balance == -1:
                if self.left.balance == 1:
                    self.replace(p, self.DoubleRightRotation())
                elif self.left.balance == -1:
                    self.replace(p, self.SingleRightRotation())
                return False  # rotationを行うと成長しない
        if self.key < key:
            if self.right is None:
                self.right = Avltree(key)
            else:
                if not self.right.insertx(self, key):
                    return False
            if self.balance == -1:
                self.balance = 0
                return False
            elif self.balance == 0:
                self.balance = 1
                return True
            elif self.balance == 1:
                if self.right.balance == -1:
                    self.replace(p, self.DoubleLeftRotation())
                elif self.right.balance == 1:
                    self.replace(p, self.SingleLeftRotation())
                return False
        return False  # self.key == key の時は何もしないので成長もしない

    def to_s(self):
        return self.key
    def left_s(self):
        if self.left is None:
            return None
        return (self.left).key
    def right_s(self):
        if self.right is None:
            return None
        return (self.right).key
# END CUT HERE

def main():
    N = ii()
    P = lmi()
    L = [0 for i in range(N)]
    for i in range(N):
        L[P[i] - 1] = i
    L.reverse()
    ans = 0
    rb = Avltree()
    for num, i in enumerate(L):
        rb.insert(i)
        l1 = rb.search_lower(i, -1)
        l2 = rb.search_lower(l1, -1)
        r1 = rb.search_higher(i, N)
        r2 = rb.search_higher(r1, N)
        # debug(l2, l1, r1, r2)
        ans += (abs(i - l1) * abs(r2 - r1) + abs(l1 - l2) * abs(r1 - i)) * (N - num)
    print(ans)
    # print(rb.inorder())
    return



if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-
import sys
from bisect import bisect_left, bisect_right
from operator import itemgetter
from fractions import gcd
from math import ceil, floor, sqrt
from copy import deepcopy
from collections import Counter, deque
import heapq
from functools import reduce
from random import shuffle
sys.setrecursionlimit(200000)
# local only
# if not __debug__:
#     fin = open('text.txt', 'r')
#     sys.stdin = fin
# local only
input = sys.stdin.readline
def ii(): return int(input())
def mi(): return map(int, input().rstrip().split())
def lmi(): return list(map(int, input().rstrip().split()))
def li(): return list(input().rstrip())
def debug(*args, sep=" ", end="\n"): print("debug:", *args, file=sys.stderr, sep=sep, end=end) if not __debug__ else None
def exit(*arg): print(*arg); sys.exit()
# template

# BEGIN CUT HERE
class Avltree:
    """
    AVL木

    Methods
    -------
        search(x: int) -> Union(int)
            ◯.data == x のものが存在するある場合それを出力、ない場合 None を返す
        insert(x: int) -> None
            ◯.data == x がない場合 ◯.data == x なる頂点を作る。ある場合はなにもしない（上書きしない）
        y.to_s() -> int
            頂点yのdataを返す
        y.left_s() -> Union(int, key=None)
            頂点yのleftを返す(ない場合は key)
        search_lower(x: int, key_lower) -> int
            ○.data が x より小さいものの中で最も大きいものを出力、ない場合 key_lower を返す
        search_higher(x:int , key_higher) -> int
            ○.data が x より大きいものの中で最も小さいものを出力、ない場合 key_higher を返す
    """

    def __init__(self, key=None):
        self.key = key
        self.left = None
        self.right = None
        self.balance = "Even"

    def search(self, key):
        if self.key is None:
            return None
        node = self
        while node is not None:
            if node.key == key:
                return node  # node.key == keyの場合
            if node.key > key:
                node = node.left
            if node.key < key:
                node = node.right
        return None

    def search_lower(self, key, key_lower):
        node = self
        if node.key is None:
            return key_lower
        ans = key_lower
        while node is not None:
            if node.key < key:
                ans = max(ans, node.key)
                node = node.right
            elif node.key >= key:
                node = node.left
        return ans

    def search_higher(self, key, key_higher):
        node = self
        if node.key is None:
            return key_higher
        ans = key_higher
        while node is not None:
            if node.key > key:
                ans = min(ans, node.key)
                node = node.left
            elif node.key <= key:
                node = node.right
        return ans


    def end_lower(self, end_lower_key):
        node = self
        while node.left is not None:
            node = node.left
        return node.key

    def end_higher(self, end_higher_key):
        node = self
        while node.right is not None:
            node = node.right
        return node.key


    def DoubleRightRotation(self):
        tl = self.left
        self.left = tl.right.right
        tl.right.right = self  # selfはそのノード
        tlr = tl.right
        tl.right = tlr.left
        tlr.left = tl
        if tlr.balance == "Left":
            tlr.right.balance = "Right"
            tlr.left.balance = "Even"
        elif tlr.balance == "Right":
            tlr.right.balance = "Even"
            tlr.left.balance = "Left"
        elif tlr.balance == "Even":
            tlr.right.balance = "Even"
            tlr.left.balance = "Even"
        tlr.balance = "Even"
        return tlr
    def DoubleLeftRotation(self):
        tr = self.right
        self.right = tr.left.left
        tr.left.left = self
        trl = tr.left
        tr.left = trl.right
        trl.right = tr
        if trl.balance == "Right":
            trl.left.balance = "Left"
            trl.right.balance = "Even"
        elif trl.balance == "Left":
            trl.left.balance = "Even"
            trl.right.balance = "Right"
        elif trl.balance == "Even":
            trl.left.balance = "Even"
            trl.right.balance = "Even"
        trl.balance = "Even"
        return trl
    def SingleLeftRotation(self):
        tr = self.right
        tr.balance = "Even"
        self.balance = "Even"
        self.right = tr.left
        tr.left = self
        return tr
    def SingleRightRotation(self):
        tl = self.left
        tl.balance = "Even"
        self.balance = "Even"
        self.left = tl.right
        tl.right = self
        return tl
    def replace(self, p, v):  # 親ノードpの下にある自分(self)をvに置き換える。
        if p.left == self:
            p.left = v
        else:
            p.right = v
    def insert(self, key):  # rootでのみ呼ばれる挿入
        if self.key is None:  # rootを含むrotationはしないことにする。
            self.key = key
            return self
        if key < self.key:
            if self.left is None:
                self.left = Avltree(key)
            else:
                self.left.insertx(self, key)
        elif key > self.key:
            if self.right is None:
                self.right = Avltree(key)
            else:
                self.right.insertx(self, key)
        else:  # key == self.key:
            pass  # do not overwrite
    def insertx(self, p, key):  # replaceを呼ぶために一つ上の親を持っているinsert
        if self.key > key:
            if self.left is None:
                self.left = Avltree(key)
            else:
                if not self.left.insertx(self, key):  # 左の木が生長しなければ、
                    return False  # 成長しない
            if self.balance == "Right":
                self.balance = "Even"
                return False
            elif self.balance == "Even":
                self.balance = "Left"
                return True  # 成長した
            elif self.balance == "Left":
                if self.left.balance == "Right":
                    self.replace(p, self.DoubleRightRotation())
                elif self.left.balance == "Left":
                    self.replace(p, self.SingleRightRotation())
                return False  # rotationを行うと成長しない
        if self.key < key:
            if self.right is None:
                self.right = Avltree(key)
            else:
                if not self.right.insertx(self, key):
                    return False
            if self.balance == "Left":
                self.balance = "Even"
                return False
            elif self.balance == "Even":
                self.balance = "Right"
                return True
            elif self.balance == "Right":
                if self.right.balance == "Left":
                    self.replace(p, self.DoubleLeftRotation())
                elif self.right.balance == "Right":
                    self.replace(p, self.SingleLeftRotation())
                return False
        return False  # self.key == key の時は何もしないので成長もしない

    def to_s(self):
        return self.key
    def left_s(self):
        if self.left is None:
            return None
        return (self.left).key
    def right_s(self):
        if self.right is None:
            return None
        return (self.right).key
# END CUT HERE

def main():
    N = ii()
    P = lmi()
    L = [0 for i in range(N)]
    for i in range(N):
        L[P[i] - 1] = i
    L.reverse()
    ans = 0
    rb = Avltree()
    for num, i in enumerate(L):
        rb.insert(i)
        l1 = rb.search_lower(i, -1)
        l2 = rb.search_lower(l1, -1)
        r1 = rb.search_higher(i, N)
        r2 = rb.search_higher(r1, N)
        debug(l2, l1, r1, r2)
        ans += (abs(i - l1) * abs(r2 - r1) + abs(l1 - l2) * abs(r1 - i)) * (N - num)
    print(ans)
    # print(rb.inorder())
    return



if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
import bisect
N=int(input())
P=list(map(int, input().split()))
index=[0 for i in range(N+1)]
for i, p in enumerate(P):
  index[p]=i+1
s=[0, 0, N+1, N+1]
res=0
for p in range(N, 0, -1):
  idx=index[p]
  i=bisect.bisect_left(s, idx)
  s.insert(i, idx)
  res+=p*((s[i-1]-s[i-2])*(s[i+1]-s[i])+(s[i+2]-s[i+1])*(s[i]-s[i-1]))
print(res)

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-
import sys
from bisect import bisect_left, bisect_right
from operator import itemgetter
from fractions import gcd
from math import ceil, floor, sqrt
from copy import deepcopy
from collections import Counter, deque
import heapq
from functools import reduce
from random import shuffle
sys.setrecursionlimit(200000)
# local only
# if not __debug__:
#     fin = open('text.txt', 'r')
#     sys.stdin = fin
# local only
input = sys.stdin.readline
def ii(): return int(input())
def mi(): return map(int, input().rstrip().split())
def lmi(): return list(map(int, input().rstrip().split()))
def li(): return list(input().rstrip())
def debug(*args, sep=" ", end="\n"): print("debug:", *args, file=sys.stderr, sep=sep, end=end) if not __debug__ else None
def exit(*arg): print(*arg); sys.exit()
# template

# BEGIN CUT HERE
class Avltree:
    """
    AVL木

    Methods
    -------
        search(x: int) -> Union(int)
            ◯.data == x のものが存在するある場合それを出力、ない場合 None を返す
        insert(x: int) -> None
            ◯.data == x がない場合 ◯.data == x なる頂点を作る。ある場合はなにもしない（上書きしない）
        y.to_s() -> int
            頂点yのdataを返す
        y.left_s() -> Union(int, key=None)
            頂点yのleftを返す(ない場合は key)
        search_lower(x: int, key_lower) -> int
            ○.data が x より小さいものの中で最も大きいものを出力、ない場合 key_lower を返す
        search_higher(x:int , key_higher) -> int
            ○.data が x より大きいものの中で最も小さいものを出力、ない場合 key_higher を返す
    """

    def __init__(self, key=None):
        self.key = key
        self.left = None
        self.right = None
        self.balance = "Even"

    def search(self, key):
        if self.key is None:
            return None
        node = self
        while True:
            if node.key == key:
                return node  # node.key == keyの場合
            if node.key > key:
                if node.left is None:
                    return None
                else:
                    node = node.left
            if node.key < key:
                if node.right is None:
                    return None
                else:
                    node = node.right

    def search_lower(self, key, key_lower):
        node = self
        if node.key is None:
            return key_lower
        ans = key_lower
        while node is not None:
            if node.key < key:
                ans = max(ans, node.key)
                node = node.right
            elif node.key >= key:
                node = node.left
        return ans

    def search_higher(self, key, key_higher):
        node = self
        if node.key is None:
            return key_higher
        ans = key_higher
        while node is not None:
            if node.key > key:
                ans = min(ans, node.key)
                node = node.left
            elif node.key <= key:
                node = node.right
        return ans


    def end_lower(self, end_lower_key):
        node = self
        while node.left is not None:
            node = node.left
        return node.key

    def end_higher(self, end_higher_key):
        node = self
        while node.right is not None:
            node = node.right
        return node.key


    def DoubleRightRotation(self):
        tl = self.left
        self.left = tl.right.right
        tl.right.right = self  # selfはそのノード
        tlr = tl.right
        tl.right = tlr.left
        tlr.left = tl
        if tlr.balance == "Left":
            tlr.right.balance = "Right"
            tlr.left.balance = "Even"
        elif tlr.balance == "Right":
            tlr.right.balance = "Even"
            tlr.left.balance = "Left"
        elif tlr.balance == "Even":
            tlr.right.balance = "Even"
            tlr.left.balance = "Even"
        tlr.balance = "Even"
        return tlr
    def DoubleLeftRotation(self):
        tr = self.right
        self.right = tr.left.left
        tr.left.left = self
        trl = tr.left
        tr.left = trl.right
        trl.right = tr
        if trl.balance == "Right":
            trl.left.balance = "Left"
            trl.right.balance = "Even"
        elif trl.balance == "Left":
            trl.left.balance = "Even"
            trl.right.balance = "Right"
        elif trl.balance == "Even":
            trl.left.balance = "Even"
            trl.right.balance = "Even"
        trl.balance = "Even"
        return trl
    def SingleLeftRotation(self):
        tr = self.right
        tr.balance = "Even"
        self.balance = "Even"
        self.right = tr.left
        tr.left = self
        return tr
    def SingleRightRotation(self):
        tl = self.left
        tl.balance = "Even"
        self.balance = "Even"
        self.left = tl.right
        tl.right = self
        return tl
    def replace(self, p, v):  # 親ノードpの下にある自分(self)をvに置き換える。
        if p.left == self:
            p.left = v
        else:
            p.right = v
    def insert(self, key):  # rootでのみ呼ばれる挿入
        if self.key is None:  # rootを含むrotationはしないことにする。
            self.key = key
            return self
        if key < self.key:
            if self.left is None:
                self.left = Avltree(key)
            else:
                self.left.insertx(self, key)
        elif key > self.key:
            if self.right is None:
                self.right = Avltree(key)
            else:
                self.right.insertx(self, key)
        else:  # key == self.key:
            pass  # do not overwrite
    def insertx(self, p, key):  # replaceを呼ぶために一つ上の親を持っているinsert
        if self.key > key:
            if self.left is None:
                self.left = Avltree(key)
            else:
                if not self.left.insertx(self, key):  # 左の木が生長しなければ、
                    return False  # 成長しない
            if self.balance == "Right":
                self.balance = "Even"
                return False
            elif self.balance == "Even":
                self.balance = "Left"
                return True  # 成長した
            elif self.balance == "Left":
                if self.left.balance == "Right":
                    self.replace(p, self.DoubleRightRotation())
                elif self.left.balance == "Left":
                    self.replace(p, self.SingleRightRotation())
                return False  # rotationを行うと成長しない
        if self.key < key:
            if self.right is None:
                self.right = Avltree(key)
            else:
                if not self.right.insertx(self, key):
                    return False
            if self.balance == "Left":
                self.balance = "Even"
                return False
            elif self.balance == "Even":
                self.balance = "Right"
                return True
            elif self.balance == "Right":
                if self.right.balance == "Left":
                    self.replace(p, self.DoubleLeftRotation())
                elif self.right.balance == "Right":
                    self.replace(p, self.SingleLeftRotation())
                return False
        return False  # self.key == key の時は何もしないので成長もしない

    def to_s(self):
        return self.key
    def left_s(self):
        if self.left is None:
            return None
        return (self.left).key
    def right_s(self):
        if self.right is None:
            return None
        return (self.right).key
# END CUT HERE

def main():
    N = ii()
    P = lmi()
    L = [0 for i in range(N)]
    for i in range(N):
        L[P[i] - 1] = i
    L.reverse()
    ans = 0
    rb = Avltree()
    for num, i in enumerate(L):
        rb.insert(i)
        l1 = rb.search_lower(i, -1)
        l2 = rb.search_lower(l1, -1)
        r1 = rb.search_higher(i, N)
        r2 = rb.search_higher(r1, N)
        debug(l2, l1, r1, r2)
        ans += (abs(i - l1) * abs(r2 - r1) + abs(l1 - l2) * abs(r1 - i)) * (N - num)
    print(ans)
    # print(rb.inorder())
    return



if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
Pn = list(map(int, input().split()))
ret = 0
for i in range(N - 1):
    for j in range(i + 1, N):
        ret += sorted(Pn[i:j + 1])[-2]
print(ret)

Submission status: Time Limit Exceeded

Solution code:
n = int(input())
l = list(map(int, input().split()))
ans = [-1, -1, n, n]
result = 0

for i in range(n):
    now = l.index(n-i)
#    print(now)
    ans.append(now)
    ans.sort()
    ans_now = ans.index(now)
    result += ((ans[ans_now] - ans[ans_now-1]) * (ans[ans_now+2] - ans[ans_now+1]) + (ans[ans_now+1] - ans[ans_now]) * (ans[ans_now-1] - ans[ans_now-2])) * (n-i)
#    print(ans, result)
print(result)

Submission status: Time Limit Exceeded

Solution code:
n = int(input())
ListP = [int(i) for i in input().split()]
#ListPosPのPositionは1からnまでの値
ListPosP = [ListP.index(i) for i in range(1, n+1)]
points = 0
for i in reversed(range(1, n)):
	ListDistPlus = sorted([j - ListPosP[i-1] for j in ListPosP[i:] if j - ListPosP[i-1] > 0])
	ListDistMinus = sorted([j - ListPosP[i-1] for j in ListPosP[i:] if j - ListPosP[i-1] < 0])
	#Plus側のiより大きい値を1つだけ含む部分配列
	if (len(ListDistPlus) == 1):
		ListDistPlus = ListDistPlus + [n+1-(ListPosP[i-1] + 1)]
	if (len(ListDistPlus) == 0):
		ListDistPlus = [n+1-(ListPosP[i-1] + 1), n+1-(ListPosP[i-1] + 1)]
	if (len(ListDistMinus) == 1):
		ListDistMinus = [-(ListPosP[i-1] + 1)] + ListDistMinus
	if (len(ListDistMinus) == 0):
		ListDistMinus = [-(ListPosP[i-1] + 1), -(ListPosP[i-1] + 1)]
	points += i * ((ListDistPlus[1] - ListDistPlus[0]) * (-ListDistMinus[-1]) + (ListDistMinus[-1] - ListDistMinus[-2]) * (ListDistPlus[0]))
	#print(points)デバッグ用
	#print(ListDistMinus[-1], ListDistMinus[-2], ListDistPlus[0], ListDistPlus[1])デバッグ用
print(points)

Submission status: Time Limit Exceeded

Solution code:
'''解説動画を見て実装'''
import bisect
N = int(input())
P = [int(x)-1 for x in input().split()]

idx = [None]*N

for i, p in enumerate(P):
    idx[p] = i

ans = 0
s = []  # ordered set をリストで代用 (bisect.insort で挿入)
sidx = []  # index for set
for x in range(N-1, -1, -1):
    i = idx[x]
    c = 0  # 組み合わせの個数
    ins = bisect.bisect_left(s, i)
    s.insert(ins, i)
    # print(s)
    lpos = [-1, -1]  # x より左側で x より大きい数の位置
    rpos = [N, N]  # x より左側で x より大きい数の位置

    # 左側の探索
    it = ins  # iterator
    for j in range(2):
        if it == 0:
            break
        it -= 1
        lpos[j] = s[it]

    # 右側の探索
    it = ins
    for j in range(2):
        it += 1
        if it == len(s):
            break
        rpos[j] = s[it]

    c = (i-lpos[0])*(rpos[1]-rpos[0]) + (lpos[0]-lpos[1])*(rpos[0]-i)
    ans += c*(x+1)
print(ans)

Submission status: Time Limit Exceeded

Solution code:
'''解説動画を見て実装'''
import bisect
N = int(input())
P = [int(x)-1 for x in input().split()]

idx = [None]*N

for i, p in enumerate(P):
    idx[p] = i

ans = 0
s = []  # ordered set をリストで代用 (bisect.insort で挿入)
sidx = []  # index for set
for x in range(N-1, -1, -1):
    i = idx[x]
    c = 0  # 組み合わせの個数
    ins = bisect.bisect_left(s, i)
    s.insert(ins, i)
    # print(s)
    lpos = [-1, -1]  # x より左側で x より大きい数の位置
    rpos = [N, N]  # x より左側で x より大きい数の位置

    # 左側の探索
    it = ins  # iterator
    for j in range(2):
        if it == 0:
            break
        it -= 1
        lpos[j] = s[it]

    # 右側の探索
    it = ins
    for j in range(2):
        it += 1
        if it == len(s):
            break
        rpos[j] = s[it]
    ls = (i-lpos[0], lpos[0]-lpos[1])
    rs = (rpos[0]-i, rpos[1]-rpos[0])
    c = ls[0]*rs[1] + ls[1]*rs[0]

    ans += c*(x+1)
print(ans)

Submission status: Time Limit Exceeded

Solution code:
'''解説動画を見て実装'''
import bisect
N = int(input())
P = [int(x)-1 for x in input().split()]

idx = [None]*N

for i, p in enumerate(P):
    idx[p] = i

ans = 0
s = []  # ordered set をリストで代用 (bisect.insort で挿入)
sidx = []  # index for set
for x in range(N-1, -1, -1):
    i = idx[x]
    c = 0  # 組み合わせの個数
    ins = bisect.bisect_left(s, i)
    s.insert(ins, i)
    # print(s)
    lpos = [-1]*2  # x より左側で x より大きい数の位置
    rpos = [N]*2  # x より左側で x より大きい数の位置

    # 左側の探索
    it = ins  # iterator
    for j in range(2):
        if it == 0:
            break
        it -= 1
        lpos[j] = s[it]

    # 右側の探索
    it = ins
    for j in range(2):
        it += 1
        if it == len(s):
            break
        rpos[j] = s[it]
    ls = (i-lpos[0], lpos[0]-lpos[1])
    rs = (rpos[0]-i, rpos[1]-rpos[0])
    c = ls[0]*rs[1] + ls[1]*rs[0]

    ans += c*(x+1)
print(ans)

Submission status: Time Limit Exceeded

Solution code:
'''解説動画を見て実装'''
import bisect
N = int(input())
P = [int(x)-1 for x in input().split()]

idx = [None]*N

for i, p in enumerate(P):
    idx[p] = i

ans = 0
s = []  # ordered set をリストで代用 (bisect.insort で挿入)
sidx = []  # index for set
for x in range(N-1, -1, -1):
    i = idx[x]
    c = 0  # 組み合わせの個数
    ins = bisect.bisect_left(s, i)
    s.insert(ins, i)
    # print(s)
    lpos = [-1]*2  # x より左側で x より大きい数の位置
    rpos = [N]*2  # x より左側で x より大きい数の位置

    # 左側の探索
    it = s.index(i)  # iterator
    it2 = it
    for j in range(2):
        if it == 0:
            break
        it -= 1
        lpos[j] = s[it]

    # 右側の探索
    for j in range(2):
        it2 += 1
        if it2 == len(s):
            break
        rpos[j] = s[it2]
    ls = (i-lpos[0], lpos[0]-lpos[1])
    rs = (rpos[0]-i, rpos[1]-rpos[0])
    c = ls[0]*rs[1] + ls[1]*rs[0]

    ans += c*(x+1)
print(ans)