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;

#define PII pair<int, int>

const int N = 1e5 + 5;

int n, a[N];
PII tree[4 * N];
map<PII, int> vis;

PII merge(PII x, PII y) {
  if (x.first == -1) return y;
  if (y.first == -1) return x;
  return x.first > y.first ? x : y;
}

void build(int p, int b, int e) {
  if (b == e) {
    tree[p].first = a[b];
    tree[p].second = b;
    return;
  }
  int m = b + e >> 1;
  build(p * 2, b, m);
  build(p * 2 + 1, m + 1, e);
  tree[p] = merge(tree[p * 2], tree[p * 2 + 1]);
}

PII query(int p, int b, int e, int l, int r) {
  if (b > r || e < l) return {-1, -1};
  if (b >= l && e <= r) return tree[p];
  int m = b + e >> 1;
  return merge(query(p * 2, b, m, l, r), query(p * 2 + 1, m + 1, e, l, r));
}

multiset<PII> FOK, SOK;

long long run(int l, int r) {
  if (l >= r || vis[{l, r}]) return 0;
  PII yo = query(1, 1, n, l, r);
  PII mg = merge(query(1, 1, n, l, yo.second - 1), query(1, 1, n, yo.second + 1, r));
  int L = min(yo.second, mg.second);
  int R = max(yo.second, mg.second);
  int peche = L - l + 1;
  int shamne = r - R + 1;
  /*for (int i = l; i <= L; i++) {
    for (int j = R; j <= r; j++) {
      FOK.insert({i, j});
      if (i == 4 && j == 5) {
        cout << i << " " << j << endl;
      }
    }
  }*/
  vis[{l, r}] = 1;
  long long ans = (long long)mg.first * (long long)peche * (long long)shamne;
  //cout << ans << " " << l << " " << L << " " << R << " " << r << endl;
  return ans + run(l, R - 1) + run(L + 1, r);
}

long long brute() {
  long long sum = 0;
  for (int i = 1; i <= n; i++) {
    int fs = a[i], sn = -1;
    for (int j = i + 1; j <= n; j++) {
      if (sn == -1) {
        sn = a[j];
        int tmp = max(fs, sn);
        sn = min(fs, sn);
        fs = tmp;
      } else if (fs < a[j]) {
        sn = fs;
        fs = a[j];
      } else if (sn < a[j]) {
        sn = a[j];
      }
      SOK.insert({i, j});
      //cout << i << " " << j << " " << sn << endl;
      sum += sn;
    }
  }
  return sum;
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  build(1, 1, n);
  cout << run(1, n) << '\n';
  /*cout << "BRUTE: " << brute() << '\n';
  for (auto i : FOK) {
    cout << i.first << " " << i.second << endl;
  }
  cout << FOK.size() << " " << SOK.size() << endl; */
  return 0;
}