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: Wrong Answer)

using System;
using System.Linq;
using System.Collections.Generic;

using E = System.Linq.Enumerable;

public class Program
{
    public static void Main()
    {
        var n = int.Parse(Console.ReadLine());
        var seqP = Console.ReadLine().Split().Select(x => int.Parse(x)).ToArray();

        Array.Reverse(seqP);
        var lower = SearchNearestGreaters(seqP);
        Array.Reverse(seqP);
        var upper = SearchNearestGreaters(seqP);

        Array.Reverse(lower);
        for (int i = 0; i < lower.Length; ++i)
        for (int j = 0; j < lower[i].Length; ++j)
        {
            lower[i][j] = lower.Length - lower[i][j] - 1;
        }

        Console.Error.WriteLine(string.Join(" ", lower.Select(x => x[1])));
        Console.Error.WriteLine(string.Join(" ", lower.Select(x => x[0])));
        Console.Error.WriteLine(string.Join(" ", upper.Select(x => x[0])));
        Console.Error.WriteLine(string.Join(" ", upper.Select(x => x[1])));

        var sum = 0L;
        for (int i = 0; i < seqP.Length; ++i)
        {
            var w = lower[i][1];
            var x = lower[i][0];
            var y = upper[i][0];
            var z = upper[i][1];
            sum += seqP[i] * ((x - w) * (y - i) + (i - x) * (z - y));
        }

        Console.WriteLine(sum);
    }

    static int[][] SearchNearestGreaters(int[] seqP)
    {
        var xs = new int[seqP.Length][];
        var bookmarks = new Stack<int>[3];
        for (int i = 0; i < bookmarks.Length; ++i)
        {
            bookmarks[i] = new Stack<int>();
        }
        var cache = new Stack<int>();
        for (int i = 0; i < seqP.Length; ++i)
        {
            xs[i] = new int[] { -1, -1 };
            bookmarks[0].Push(i);
            for (int k = 0; k < bookmarks.Length; ++k)
            {
                if (k + 1 >= bookmarks.Length)
                {
                    break;
                }

                int ii = Math.Min(seqP.Length, i + 1 + k);
                var t = ii < seqP.Length ? seqP[ii] : long.MaxValue;
                while (bookmarks[k].Any() && seqP[bookmarks[k].Peek()] < t)
                {
                    int j = bookmarks[k].Pop();
                    cache.Push(j);
                    xs[j][k] = ii;
                }
                while (cache.Any())
                {
                    bookmarks[k + 1].Push(cache.Pop());
                }
            }
        }
        Console.Error.WriteLine();
        return xs;
    }
}