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.Linq;
using System.Collections.Generic;
using static System.Console;
using System.Text;
using System.IO;

namespace AtCoder
{
    class Program
    {
        static public long[] Sarray() { return ReadLine().Split().Select(long.Parse).ToArray(); }
        static public List<long> Slist() { return ReadLine().Split().Select(long.Parse).ToList(); }

        //平行二分探索木。参考(http://wwwa.pikara.ne.jp/okojisan/avl-tree/index.html)
        class BinarySearchTree<T> where T : IComparable<T>
        {
            class node
            {
                public node left = null;
                public node right = null;
                public T key = default(T);
                public node parent = null;
                public int height;
            }
            node root = null;
            bool change;
            int height(node t) => t?.height ?? 0;
            int bias(node t) => height(t.left) - height(t.right);
            void modHeight(node t) => t.height = 1 + Math.Max(height(t.left), height(t.right));
            node rotateL(node v)
            {
                var u = v.right;
                var t2 = u.left;
                u.left = v; u.parent = v.parent; v.parent = u;
                if (u.parent != null)
                    if (u.parent.right == v) u.parent.right = u;
                    else u.parent.left = u;
                else
                    root = u;
                v.right = t2; if (t2 != null) t2.parent = v;
                modHeight(u.left);
                modHeight(u);
                return u;
            }
            node rotateR(node u)
            {
                var v = u.left;
                var t2 = v.right;
                v.right = u;v.parent = u.parent;u.parent = v;
                if (v.parent != null)
                    if (v.parent.right == u) v.parent.right = v;
                    else v.parent.left = v;
                else
                    root = v;
                u.left = t2;if (t2 != null) t2.parent = u;
                modHeight(v.right);
                modHeight(v);
                return v;
            }
            node rotateLR(node t)
            {
                t.left = rotateL(t.left);
                return rotateR(t);
            }
            node rotateRL(node t)
            {
                t.right = rotateR(t.right);
                return rotateL(t);
            }
            node balanceLi(node t) => balanceL(t);
            node balanceRi(node t) => balanceR(t);
            node balanceLd(node t) => balanceR(t);
            node balanceRd(node t) => balanceL(t);

            node balanceL(node t)
            {
                if (!change) return t;
                var h = height(t);
                if (bias(t) == 2)
                {
                    if (0 <= bias(t.left))
                        t = rotateR(t);
                    else
                        t = rotateLR(t);
                }
                else modHeight(t);
                change = (h != height(t));
                return t;
            }
            node balanceR(node t)
            {
                if (!change) return t;
                var h = height(t);
                if (bias(t) == -2)
                {
                    if (bias(t.right) <= 0)
                        t = rotateL(t);
                    else
                        t = rotateRL(t);
                }
                else modHeight(t);
                change = (h != height(t));
                return t;
            }


            public BinarySearchTree() { }

            public void insert(T z)
            {
                change = true;
                _insert(new node() { key = z, height = 1 });
            }
            void _insert(node z)
            {
                node y = null;
                node x = root;
                while (x != null)
                {
                    y = x;
                    if (z.key.CompareTo(x.key) < 0)
                        x = x.left;
                    else
                        x = x.right;
                }
                if (y == null)
                {
                    root = z;
                    change = false;
                }
                else if (z.key.CompareTo(y.key) < 0)
                {
                    y.left = z;
                    y.left.parent = y;
                }
                else
                {
                    y.right = z;
                    y.right.parent = y;
                }
                var s = z;
                while (s.parent != null)
                {
                    if (s.parent.left == s)
                        s = balanceLi(s.parent);
                    else
                        s = balanceRi(s.parent);
                }
            }
            public bool find(T v)
            {
                var n = _find(v);
                return n == null ? false : true;
            }
            node _find(T v)
            {
                var x = root;
                while (x != null)
                {
                    if (x.key.CompareTo(v) == 0)
                        return x;
                    if (x.key.CompareTo(v) < 0)
                        x = x.right;
                    else
                        x = x.left;
                }
                return null;
            }

            public void delete(T v) {
                change = true;
                _delete(_find(v));
            }
            void _delete(node n)
            {
                if (n == null)
                    return;
                if (n == root)
                {
                    change = false;
                    if (n.left == null && n.right == null)
                        root = null;
                    else if (n.left != null && n.right == null)
                    {
                        root = n.left;
                        root.parent = null;
                    }
                    else if (n.left == null && n.right != null)
                    {
                        root = n.right;
                        root.parent = null;
                    }
                    else
                    {
                        var next = n.right;
                        while (next.left != null)
                            next = next.left;
                        n.key = next.key;
                        change = true;
                        _delete(next);
                    }
                    return;
                }
                var spl = n.parent.left;
                if (n.left == null && n.right == null)
                {
                    if (n == n.parent.right)
                        n.parent.right = null;
                    else
                        n.parent.left = null;
                }
                else if (n.left != null && n.right == null)
                {
                    n.left.parent = n.parent;
                    if (n == n.parent.right)
                        n.parent.right = n.left;
                    else
                        n.parent.left = n.left;
                }
                else if (n.left == null && n.right != null)
                {
                    n.right.parent = n.parent;
                    if (n == n.parent.right)
                        n.parent.right = n.right;
                    else
                        n.parent.left = n.right;
                }
                else
                {
                    var next = n.right;
                    while (next.left != null)
                        next = next.left;
                    n.key = next.key;
                    _delete(next);
                }
                var s = n;
                while (s.parent != null)
                {
                    if (spl == s)
                        s = balanceLd(s.parent);
                    else
                        s = balanceRd(s.parent);
                    spl = s.parent?.left;
                }
            }

            List<T> preorder;
            public IReadOnlyList<T> PreOrder { get { return preorder.AsReadOnly(); } }
            List<T> inorder;
            public IReadOnlyList<T> InOrder { get { return inorder.AsReadOnly(); } }
            public void order()
            {
                preorder = new List<T>();
                inorder = new List<T>();
                _order(root);
            }
            void _order(node n)
            {
                if (n == null)
                    return;
                preorder.Add(n.key);
                _order(n.left);
                inorder.Add(n.key);
                _order(n.right);
            }
            public bool prev(T v, ref T r)
            {
                var t = _find(v);
                if (null == t)
                    return false;
                if (null != t.left)
                {
                    t = t.left;
                    while (t.right != null)
                        t = t.right;
                    r = t.key;
                    return true;
                }
                while (t.parent != null)
                {
                    if (t.parent.right == t)
                    {
                        r = t.parent.key;
                        return true;
                    }
                    t = t.parent;
                }
                return false;
            }
            public bool next(T v, ref T r)
            {
                var t = _find(v);
                if (null == t)
                    return false;
                if (null != t.right)
                {
                    t = t.right;
                    while (t.left != null)
                        t = t.left;
                    r = t.key;
                    return true;
                }
                while (t.parent != null)
                {
                    if (t.parent.left == t)
                    {
                        r = t.parent.key;
                        return true;
                    }
                    t = t.parent;
                }
                return false;
            }
        }
        static void Main(string[] args)
        {
            var N = Sarray()[0];
            var P = Sarray();
            var bst = new BinarySearchTree<long>();
            var idx = new long[N];
            for (long i = 0; i < N; ++i)
                idx[P[i] - 1] = i;

            long ans = 0L;
            for (var i = N - 1; 0 <= i; --i)
            {
                long ll = -1;
                long l = -1;
                long r = N;
                long rr = N;
                bst.insert(idx[i]);
                bst.prev(idx[i], ref l);
                bst.prev(l, ref ll);
                bst.next(idx[i], ref r);
                bst.next(r, ref rr);
                ans += (i + 1) * ((l - ll) * (r - idx[i]) + (rr - r) * (idx[i] - l));
            }
            WriteLine(ans);
        }
    }
}