Range Sorting (Hard Version) (Codeforces 1827B2)
Tags: Greedy, binary search

The only difference between this problem and the easy version is the constraints on $$$t$$$ and $$$n$$$.You are given an array $$$a$$$, consisting of $$$n$$$ distinct integers $$$a_1, a_2, \ldots, a_n$$$. Define the beauty of an array $$$p_1, p_2, \ldots p_k$$$ as the minimum amount of time needed to sort this array using an arbitrary number of range-sort operations. In each range-sort operation, you will do the following:   Choose two integers $$$l$$$ and $$$r$$$ ($$$1 \le l < r \le k$$$).  Sort the subarray $$$p_l, p_{l + 1}, \ldots, p_r$$$ in $$$r - l$$$ seconds. Please calculate the sum of beauty over all subarrays of array $$$a$$$.A subarray of an array is defined as a sequence of consecutive elements of the array.

Input: Each test contains multiple test cases. The first line contains the number of test cases $$$t$$$ ($$$1 \le t \le 10^4$$$). The description of the test cases follows.The first line of each test case contains a single integer $$$n$$$ ($$$1 \le n \le 3 \cdot 10^5$$$) — the length of the array $$$a$$$.The second line of each test case consists of $$$n$$$ integers $$$a_1,a_2,\ldots, a_n$$$ ($$$1\le a_i\le 10^9$$$). It is guaranteed that all elements of $$$a$$$ are pairwise distinct.It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$3 \cdot 10^5$$$.

Output: For each test case, output the sum of beauty over all subarrays of array $$$a$$$.

Note: In the first test case:   The subarray $$$[6]$$$ is already sorted, so its beauty is $$$0$$$.  The subarray $$$[4]$$$ is already sorted, so its beauty is $$$0$$$.  You can sort the subarray $$$[6, 4]$$$ in one operation by choosing $$$l = 1$$$ and $$$r = 2$$$. Its beauty is equal to $$$1$$$.  The sum of beauty over all subarrays of the given array is equal to $$$0 + 0 + 1 = 1$$$.In the second test case:   The subarray $$$[3]$$$ is already sorted, so its beauty is $$$0$$$.  The subarray $$$[10]$$$ is already sorted, so its beauty is $$$0$$$.  The subarray $$$[6]$$$ is already sorted, so its beauty is $$$0$$$.  The subarray $$$[3, 10]$$$ is already sorted, so its beauty is $$$0$$$.  You can sort the subarray $$$[10, 6]$$$ in one operation by choosing $$$l = 1$$$ and $$$r = 2$$$. Its beauty is equal to $$$2 - 1 = 1$$$.  You can sort the subarray $$$[3, 10, 6]$$$ in one operation by choosing $$$l = 2$$$ and $$$r = 3$$$. Its beauty is equal to $$$3 - 2 = 1$$$.  The sum of beauty over all subarrays of the given array is equal to $$$0 + 0 + 0 + 0 + 1 + 1 = 2$$$.

Sample Inputs:
5
2
6 4
3
3 10 6
4
4 8 7 2
5
9 8 2 4 6
12
2 6 13 3 15 5 10 8 16 9 11 18

Sample Outputs:
1
2
8
16
232

Solution (Python):
from collections import deque as dq
for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    ans = n * (n ** 2 - 1) // 6
    st = dq()
    st2 = dq()
    x = [-1] * n
    k = [-1] * n
    y = [n] * n
    for i in range(n - 1, -1, -1):
        while st2 and a[i] > a[st2[-1]]:
            x[st2[-1]] = i
            st2.pop()
        while st and a[i] < a[st[-1]]:
            k[st[-1]] = i
            st2.append(st[-1])
            st.pop()
        if st:
            y[i] = st[-1]
        st.append(i)
    for i in range(1, n):
        ans -= (k[i] - x[i]) * (y[i] - i)
    print(ans)

Solution (Python):
from collections import deque as dq
for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    ans = n * (n ** 2 - 1) // 6
    st = dq()
    st2 = dq()
    x = [-1] * n
    k = [-1] * n
    y = [n] * n
    for i in range(n - 1, -1, -1):
        while st2 and a[i] > a[st2[-1]]:
            x[st2[-1]] = i
            st2.pop()
        while st and a[i] < a[st[-1]]:
            k[st[-1]] = i
            st2.append(st[-1])
            st.pop()
        if st:
            y[i] = st[-1]
        st.append(i)
    for i in range(1, n):
        ans -= (k[i] - x[i]) * (y[i] - i)
    print(ans)

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

def solve():
    n = int(input())
    a = list(map(int, input().split()))
    kpos = [-1] * n
    stack = []
    for i in range(n - 1, -1, -1):
        while stack and a[i] < a[stack[-1]]:
            curr = stack.pop()
            if kpos[curr] == -1:
                kpos[curr] = i
        stack.append(i)
    ypos = [n] * n
    stack = []
    for i in range(n):
        while stack and a[i] < a[stack[-1]]:
            curr = stack.pop()
            if ypos[curr] == n:
                ypos[curr] = i
        stack.append(i)
    xpos = [-1] * n
    stack = []
    second = []
    for i in range(n - 1, -1, -1):
        while second and a[i] > a[second[-1]]:
            curr = second.pop()
            if xpos[curr] == -1:
                xpos[curr] = i
        temp = []
        while stack and a[i] < a[stack[-1]]:
            curr = stack.pop()
            if xpos[curr] == -1:
                temp.append(curr)
        stack.append(i)
        second += temp[:]
    res = 0
    for i in range(n):
        res += (kpos[i] - xpos[i]) * (ypos[i] - i)
    print((n - 1) * n * (n + 1) // 6 - res)
t = int(input())
for _ in range(t):
    solve()