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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCorder
{
	public class Program
	{
		static void Main(string[] args)
		{
			Scanner cin = new Scanner();
			int n = cin.Int();
			int[] p = cin.ArrayInt(n);
			int[] indexes = new int[n];
			for (int i = 0; i < n; i++) {
				indexes[p[i] - 1] = i;
			}

			long ans = 0;
			var temp = new SortedList<int, int>(n);
			for (int i = n - 1; i >= 0; --i) {
				int index = indexes[i];
				temp.Add(index, index);
				int l1 = -1;
				int l2 = -1;
				int r1 = n;
				int r2 = n;

				int current = index;
				int currentIndex = temp.IndexOfKey(index);
				var keys = temp.Keys;

				if (currentIndex - 1 >= 0) {
					l1 = keys[currentIndex - 1];
				}

				if (currentIndex - 2 >= 0) {
					l2 = keys[currentIndex - 2];
				}

				if (currentIndex + 1 < temp.Count()) {
					r1 = keys[currentIndex + 1];
				}

				if (currentIndex + 2 < temp.Count()) {
					r2 = keys[currentIndex + 2];
				}

				int rangeL1 = current - l1;
				int rangeL2 = l1 - l2;
				int rangeR1 = r1 - current;
				int rangeR2 = r2 - r1;

				ans += (i + 1) * ((long)rangeL2 * rangeR1 + (long)rangeR2 * rangeL1);
			}

			Console.WriteLine(ans);
		}
	}

	public class Scanner
	{
		private readonly char[] delimiter_ = new char[] { ' ' };
		private string[] buf_;
		private int index_;

		public Scanner()
		{
			buf_ = new string[0];
			index_ = 0;
		}

		public string Next()
		{
			if (index_ < buf_.Length) {
				return buf_[index_++];
			}

			string st = Console.ReadLine();
			while (st == "") {
				st = Console.ReadLine();
			}

			buf_ = st.Split(delimiter_, StringSplitOptions.RemoveEmptyEntries);
			if (buf_.Length == 0) {
				return Next();
			}

			index_ = 0;
			return buf_[index_++];
		}

		public int Int()
		{
			return int.Parse(Next());
		}
		public int[] ArrayInt(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Int() + add;
			}
			return Array;
		}

		public long Long()
		{
			return long.Parse(Next());
		}

		public long[] ArrayLong(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Long() + add;
			}
			return Array;
		}

		public double Double()
		{
			return double.Parse(Next());
		}

		public double[] ArrayDouble(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Double() + add;
			}
			return Array;
		}
	}
}