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 C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>

using namespace std;

vector<int> lg;

template <typename T>
struct RMQ {
    int n;
    vector<vector<T>> table;
    RMQ(vector<int>& xs): n(xs.size()) {
        int K = lg[n] + 2;
        table = vector<vector<T>>(K, vector<T>(n, 0));
        for (int i = 0; i < n; ++i) {
            table[0][i] = xs[i];
        }
        for (int k = 1; k < K; ++k) {
            for (int i = 0; i < n; ++i) {
                int j = min(i + (1 << (k-1)), n-1);
                table[k][i] = max(table[k-1][i], table[k-1][j]);
            }
        }
    }
    T get_max(int i, int j) {
        int k = lg[j-i];
        return max(table[k][i], table[k][j - (1 << k)]);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    lg = vector<int>(n+1, 0);
    for (int i = 2; i <= n; ++i) {
        lg[i] = 1 + lg[i/2];
    }
    vector<int> ps(n);
    for (int& p : ps) {
        cin >> p;
    }
    vector<int> inv_p(n+1);
    for (int i = 0; i < n; ++i) {
        inv_p[ps[i]] = i;
    }
    RMQ<int> rmq(ps);
    function<long long (int, int)> calc_sum = [&](int l, int r) {
        if (r - l < 2) return 0LL;
        int m = inv_p[rmq.get_max(l, r)];
        deque<int> lefts, rights;
        int i = l-1;
        while (i < m-1) {
            i = inv_p[rmq.get_max(i+1, m)];
            lefts.push_back(i);
        }
        i = r;
        while (m+1 < i) {
            i = inv_p[rmq.get_max(m+1, i)];
            rights.push_back(i);
        }
        int current_left = m, current_right = m;
        int current = 0;
        long long sum = 0;
        while (!lefts.empty() || !rights.empty()) {
            if (lefts.empty() || (!rights.empty() && ps[rights.back()] < ps[lefts.back()])) {
                int new_right = rights.back();
                rights.pop_back();
                sum += ((long long) current) * ((long long) m - current_left + 1) * (new_right - current_right - 1);
                current = ps[new_right];
                current_right = new_right;
                sum += ((long long) current) * ((long long) m - current_left + 1);
            } else {
                int new_left = lefts.back();
                lefts.pop_back();
                sum += ((long long) current) * ((long long) current_right - m + 1) * (current_left - new_left - 1);
                current = ps[new_left];
                current_left = new_left;
                sum += ((long long) current) * ((long long) current_right - m + 1);
            }
        }
        // extending to [l, current_right]
        sum += ((long long) current) * ((long long) current_right - m + 1) * (current_left - l);
        // extending to [l, r-1]
        sum += ((long long) current) * ((long long) m - l + 1) * ((r-1) - current_right);
        return sum + calc_sum(l, m) + calc_sum(m+1, r);
    };
    cout << calc_sum(0, n) << endl;
    return 0;
}