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

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.io.*;
import java.util.*;

class Main {
    static Scanner scanner = new Scanner();

    public static void main(String[]$) {
        int n = scanner.nextInt();
        int[] p = new int[n];
        int[] q = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = scanner.nextInt() - 1;
            q[p[i]] = i;
        }
        long[][] a = new long[n][4];
        List<Integer> list = new ArrayList<>();
        for (int i = n - 1; i >= 0; i--) {
            int j = lowerBound(list, q[i]);
            a[i][0] = 2 <= j ? list.get(j - 2) + 1 : 0;
            a[i][1] = 1 <= j ? list.get(j - 1) + 1 : 0;
            a[i][2] = j <= list.size() - 1 ? list.get(j) : n;
            a[i][3] = j <= list.size() - 2 ? list.get(j + 1) : n;
            list.add(j, q[i]);
        }
        long ans = 0;
        for (int i = 0; i < n; i++) {
            ans += (a[i][1] - a[i][0]) * (a[i][2] - q[i]) * (i + 1);
            ans += (q[i] - a[i][1] + 1) * (a[i][3] - a[i][2]) * (i + 1);
        }
        System.out.println(ans);
    }

    static <T extends Comparable<T>> int lowerBound(List<T> list, T value) {
        int left = -1;
        int right = list.size();
        while (right - left > 1) {
            int mid = (left + right) / 2;
            if (list.get(mid).compareTo(value) < 0) {
                left = mid;
            } else {
                right = mid;
            }
        }
        return right;
    }

    static class Scanner {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in), 1 << 15);
        StringTokenizer tokenizer;

        String next() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    tokenizer = new StringTokenizer(reader.readLine());
                }
            } catch (IOException ignored) {
            }
            return tokenizer.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }
}