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;
typedef long long ll;

template <typename A>
string to_string(vector<A> v) {
    bool first = true;
    string result = "[";
    for (A i : v) {
        if (!first) result += ", ";
        first = false;
        result += to_string(i); 
    }
    return result + "]";
}

template <typename A>
string to_string(set<A> v) {
    bool first = true;
    string result = "[";
    for (A i : v) {
        if (!first) result += ", ";
        first = false;
        result += to_string(i); 
    }
    return result + "]";
}

vector<int> H;
int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); 
    ll N;
    cin >> N;
    vector<int> P (N);
    for (int i = 0; i < N; ++i) {
        H.push_back(0);
        cin >> H[i]; 
        P[i] = i;
    }

    sort(P.begin(), P.end(), [](const int a, const int b) {
        return H[a] > H[b];
    });

    ll total = 0;
    set<int> found ({-1, N});
    for (int ind : P) {
        if (H[ind] == N) {
            found.insert(ind);
            continue;
        }

        int l0 = *(--found.lower_bound(ind));
        int l1 = (l0 != -1) ? *(--found.lower_bound(l0)) : -1;
        int r0 = *found.upper_bound(ind);
        int r1 = (r0 != N) ? *found.upper_bound(r0) : N;

        int le = (l0 != -1) ? (l0 - l1) * (r0 - ind) : 0;
        int ri = (r0 != N ) ? (r1 - r0) * (ind - l0) : 0;

        total += (le + ri) * H[ind];
        found.insert(ind);
    }

    cout << total << endl;
}