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: Accepted)

#include <bits/stdc++.h>

using namespace std;
using P = pair<long, long>;

typedef long long int ll;

#define EPS (1e-7)
#define INF (1e18)
#define PI (acos(-1))

#define fillInt(xs)        \
  for (int i = 0; i < (xs).size(); i++) \
    scanf("%d", &xs[i]);
#define fillLong(xs)       \
  for (int i = 0; i < (xs).size(); i++) \
    scanf("%ld", &xs[i]);
#define fillDouble(xs)       \
  for (int i = 0; i < (xs).size(); i++) \
    scanf("%lf", &xs[i]);
#define fillString(xs)       \
  for (int i = 0; i < (xs).size(); i++) \
    cin >> xs[i];
#define sortv(xs) sort(xs.begin(), xs.end())
#define sortvinv(xs) sort(xs.begin(), xs.end(), greater<long>())
#define lbv(xs, x) lower_bound(xs.begin(), xs.end(), x) - xs.begin()
#define ubv(xs, x) upper_bound(xs.begin(), xs.end(), x) - xs.begin()
#define bs(xs, x) binary_search(xs.begin(), xs.end(), x)
#define index_of(as, x) \
  distance(as.begin(), lower_bound(as.begin(), as.end(), x))
#define rad_to_deg(rad) (((rad)/2/M_PI)*360)
#define rep(i,n) for(int i=0; i<(int)(n); i++)
#define concat(xs, ys) (xs).insert((xs).end(), (ys).begin(), (ys).end())

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  long n;
  cin >> n;

  vector<P> p;
  rep(i, n) {
    long x;
    cin >> x;
    p.push_back({x, i});
  }
  sort(p.begin(), p.end(), greater<P>());

  multiset<long> st;
  st.insert(-1);
  st.insert(-1);
  st.insert(n);
  st.insert(n);

  long res = 0;
  rep(i, n) {
    st.insert(p[i].second);
    auto idx = st.find(p[i].second);

    long up = *next(idx);
    long up2 = *next(next(idx));
    long low = *prev(idx);
    long low2 = *prev(prev(idx));

    res += (p[i].second - low) * (up2 - up) * p[i].first;
    res += (up - p[i].second) * (low - low2) * p[i].first;
  }

  cout << res << endl;
}