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;
#ifdef LOCAL_DEBUG
  #include "LOCAL_DEBUG.hpp"
#endif
#define int long long

template <class T>
struct SegmentTree{
  using F = function<T(T,T)>;
  F f;
  T inf;
  int n;
  vector<T> node;

  SegmentTree(vector<T> v,T inf,F f):inf(inf),f(f){
    n = 1; while(n < v.size()) n *= 2;
    node.resize(2*n-1,inf);
    for(int i = 0; i < v.size(); i++) node[i+n-1] = v[i];
    for(int i = n-2; i >= 0; i--) node[i] = f(node[2*i+1],node[2*i+2]);
  }

  void update(int k,T val){
    k += n-1;
    node[k] = val;
    while(k > 0){
      k = (k-1) / 2;
      node[k] = f(node[2*k+1],node[2*k+2]);
    }
  }

  void add(int k,T val){
    k += n-1;
    node[k] += val;
    while(k > 0){
      k = (k-1) / 2;
      node[k] = f(node[2*k+1],node[2*k+2]);
    }
  }

  T getval(int a,int b){ return getval(a,b,0,0,n); }
  T getval(int a,int b,int k,int l,int r){
    //区間[a, b)の値を返す
    if(r <= a || b <= l) return inf;
    if(a <= l && r <= b) return node[k];
    T vl = getval(a, b, 2*k+1, l, (l+r)/2);
    T vr = getval(a, b, 2*k+2, (l+r)/2, r);
    return f(vl, vr);
  }
};

signed main(){

  int n; cin >> n;
  vector<int> p(n),order(n);
  for(int i = 0; i < n; i++){
    cin >> p[i];
    p[i]--;
    order[p[i]] = i;
  }

  SegmentTree<int> seg(vector<int>(n,0),0,[&](int x,int y){
    return (x + y);
  });
  auto getid = [&](int num){
    int left = -2,right = n;
    while(right - left > 1){
      int mid = (left + right) / 2;

      if(seg.getval(0,mid+1) >= num) right = mid;
      else left = mid;
    }
    return right;
  };

  int ans = 0;
  for(int i = n-1; i >= 0; i--){
    seg.add(order[i],1);
    int num = seg.getval(0,order[i]+1);
    int ll = getid(num-2);
    int l = getid(num-1);
    int r = getid(num+1);
    int rr = getid(num+2);
    int res = (order[i] - l) * (rr - r) + (r - order[i]) * (l - ll);
    ans = (ans + res * (i+1));
  }
  cout << ans << endl;

  return 0;
}