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 (Clang 3.8.0) (judge verdict: Wrong Answer)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxd = 1e5+10;
int arr[maxd],id[maxd],n,l[maxd],r[maxd],ll[maxd],rr[maxd];
int ls[maxd<<4],rs[maxd<<4],sz[maxd<<4],tot,rt[maxd];
void insert(int &t,int last,int l,int r,int x)
{
    t = ++tot;  ls[t] = ls[last],rs[t] = rs[last];
    sz[t] =  sz[last]+1;
    if(l==r) return ;
    int mid = (l+r)>>1;
    if(x <= mid) insert(ls[t],ls[last],l,mid,x);
    else insert(rs[t],rs[last],mid+1,r,x);
}
int query(int x,int y,int l,int r)
{
    if(sz[y] - sz[x] == 0 ) return 0;
    if(l==r) return l;
    int mid = (l+r)>>1;
    if(sz[rs[y]] - sz[rs[x]]) return query(rs[x],rs[y],mid+1,r);
    else return query(ls[x],ls[y],l,mid);
}
int findl(int x,int y,int v)
{
    int ans = y;
    int l = x,r = y;
    while(l<=r)
    {
        int mid = (l+r)>>1;
        //printf("%d %d %d\n",mid,y,query(rt[mid],rt[y],1,n+2));
        if(query(rt[mid-1],rt[y],1,n+1) <=v) ans = mid, r = mid-1;
        else l = mid+1;
    }
    //printf("%d\n",ans);
    if(arr[ans] <= v) ans--;
    return ans;
}
int findr(int x,int y,int v)
{
    int ans = x;
    int l = x,r = y;
    while(l<=r)
    {
        int mid = (l+r)>>1;
        if(query(rt[x-1],rt[mid],1,n+1) <=v) ans = mid, l = mid+1;
        else r = mid-1;
    }
    if(arr[ans] <= v) ans++;
    return ans;
}
int main()
{
    // freopen("a.in","r",stdin);
    // freopen("k.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
    for(int i=1;i<=n;i++)
        insert(rt[i],rt[i-1],1,n+1,arr[i]);  
    insert(rt[n+1],rt[n],1,n+1,n+1); 
    long long ans = 0ll,last;
    for(int i=1;i<=n;i++)
    {
        l[i] = findl(1,i,arr[i]);
        r[i] = findr(i,n+1,arr[i]);
        rr[i] = min(findr(r[i]+1,n+1,arr[i]),n+1);
        ll[i] = max(findl(1,l[i]-1,arr[i]),0);
        //printf("%d %d %d %d %d\n",ll[i],l[i],arr[i],r[i],rr[i]);
    }
    for(int i=1;i<=n;i++)
    {
        last = ans;

        if(r[i]!=n+1) ans += 1ll*(rr[i]-r[i]) * (i-l[i]) * arr[i]; 
        if(l[i]!=0) ans += 1ll*(l[i]-ll[i]) * (r[i]-i) * arr[i];

        //printf("%d %d %lld\n",l[i],r[i],ans - last);
    }
    printf("%lld",ans);
    return 0;
}