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>

#define LL long long
#define PLL pair<LL,LL>

using namespace std;

const LL MAXN = 1000047;
const LL INF = 1000000000;

struct Vertex{
	LL l,r;
	PLL v;
	Vertex *lc,*rc;

	Vertex(LL _l, LL _r){
		l = _l;
		r = _r;
		v = {INF,l};
		if (r-l > 1){
			LL mid = (l+r)/2;
			lc = new Vertex(l,mid);
			rc = new Vertex(mid,r);
		}
		else{
			lc = nullptr;
			rc = nullptr;
		}
	}

	void update(LL _l, LL _v){
		if (r-l == 1){
			v = {_v,l};
			return;
		}
		if (_l >= rc->l){
			rc->update(_l,_v);
		}
		else{
			lc->update(_l,_v);
		}
		v = min(lc->v,rc->v);
	}

	PLL query(LL _l, LL _r){
		if (_l >= r || _r <= l){
			return {INF,INF};
		}
		if (_l <= l && _r >= r){
			return v;
		}
		return min(lc->query(_l,_r),rc->query(_l,_r));
	}

	PLL query2nd(LL _l, LL _r){
		PLL p = query(_l,_r);
		update(p.second,INF);
		PLL res = query(_l,_r);
		update(p.second,p.first);
		return res;
	}
};

int main(){
	ios_base::sync_with_stdio(false);
	LL n;
	cin >> n;
	vector<LL> a(n);
	for (LL i = 0; i < n; i++)
		cin >> a[i];
	Vertex *left = new Vertex(0,MAXN);
	Vertex *right = new Vertex(0,MAXN);
	for (LL i = 0; i < n; i++)
		right->update(a[i],i);
	LL res = 0;
	for (LL i = 0; i < n; i++){
		LL subs = 0;
		right->update(a[i],INF);
		LL r1 = (right->query(a[i]+1,MAXN)).first;
		LL r2 = (right->query2nd(a[i]+1,MAXN)).first;
		LL l1 = (left->query(a[i]+1,MAXN)).first;
		LL l2 = (left->query2nd(a[i]+1,MAXN)).first;
		// no larger on the left
		if (l1 != INF)
			l1 *= (-1);
		if (l2 != INF)
			l2 *= (-1);
		if (l1 == INF){
			if (r1 != INF){
				if (r2 == INF){
					subs += (n-r1)*(i+1);
				}
				else{
					subs += (r2-r1)*(i+1);
				}
			}
		}
		else{
			if (r1 != INF){
				if (r2 == INF){
					subs += (n-r1)*(i-l1);
				}
				else{
					subs += (r2-r1)*(i-l1);
				}
			}
		}
		// no larger on the right
		if (r1 == INF){
			if (l1 != INF){
				if (l2 == INF){
					subs += (n-i)*(l1+1);
				}
				else{
					subs += (n-i)*(l1-l2);
				}
			}
		}
		else{
			if (l1 != INF){
				if (l2 == INF){
					subs += (r1-i)*(l1+1);
				}
				else{
					subs += (r1-i)*(l1-l2);
				}
			}
		}
		left->update(a[i],-i);
		res += a[i]*subs;
	}
	cout << res << "\n";
}