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: Runtime Error)

#include  <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 5;
int t[maxn << 2], a[maxn], n, where[maxn];
int pg[maxn], ng[maxn];
ll ans = 0;
void build(int u = 1, int b = 1, int e = 100000) {
	if(b == e) return void(t[u] = a[b]);
	int m = b + e >> 1;
	build(u << 1, b, m);
	build(u << 1 | 1, m + 1, e);
	t[u] = max(t[u << 1], t[u << 1 | 1]);
}
int query(int l, int r, int u = 1, int b = 1, int e = 100000) {
	if(b > r or e < l or l > r) return 0;
	if(l <= b and e <= r) return t[u];
	int m = b + e >> 1;
	return max(query(l, r, u << 1, b, m), query(l, r, u << 1 | 1, m + 1, e));
}
int main(int argc, char const *argv[])
{
	// freopen("in", "r", stdin);
	cin >> n;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
		where[a[i]] = i;
	}
	vector<pair<int, int>> g[100];
	for(int i = 1; i <= n; i++) {
		vector<int> tmp;
		tmp.emplace_back(a[i]);
		for(int j = i + 1; j <= n; j++) {
			tmp.emplace_back(a[j]);
			sort(tmp.begin(), tmp.end());
			g[tmp[j - i - 1]].emplace_back(i, j);
		}
	}
	build();
	a[0] = a[n + 1] = maxn;
	vector<int> stk = {0};
	for(int i = 1; i <= n; i++) {
		while(a[stk.back()] < a[i]) stk.pop_back();
		pg[i] = stk.back(), stk.push_back(i);
	}
	stk = {n + 1};
	for(int i = n; i >= 1; i--) {
		while(a[stk.back()] < a[i]) stk.pop_back();
		ng[i] = stk.back(), stk.push_back(i);
	}
	pg[0] = 0, ng[n + 1] = n + 1;
	for(int i = 1; i <= n; i++) {
		int l = 0, r = 0;
		if(pg[i] > 0) {
			int lx = -1, lo = 1, hi = pg[i] - 1, mid;
			if(a[pg[i] - 1] > a[i]) lx = pg[i] - 1;
			else {
				while(lo <= hi) {
					mid = lo + hi >> 1;
					if(query(mid, pg[i] - 1) < a[i]) {
						lx = mid, hi = mid - 1;
					} else {
						lo = mid + 1;
					}
				}
				lx--;
			}
			l = pg[i] - lx;
		} else {
			l = 0;
		}
		if(ng[i] < n + 1) {
			int rx = -1, lo = ng[i] + 1, hi = n, mid;
			if(a[ng[i] + 1] > a[i]) rx = ng[i] + 1;
			else {
				while(lo <= hi) {
					mid = lo + hi >> 1;
					if(query(ng[i] + 1, mid) < a[i]) {
						rx = mid, lo = mid + 1;
					} else {
						hi = mid - 1;
					}
				}
				rx++;
			}
			r = rx - ng[i];
		} else {
			r = 0;
		}
		ll ls = ll(l) * ll(ng[i] - i);
		ll rs = ll(r) * ll(i - pg[i]);
		ans += (ls + rs) * a[i];
	}
	cout << ans << endl;
	return 0;
}