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 Rust (1.15.1) (judge verdict: Accepted)

fn read_stdin() -> String {
    use std::io::Read;
    let mut input = String::new();
    std::io::stdin().read_to_string(&mut input).unwrap();
    input
}

fn scan<'a, I: Iterator<Item = &'a str>, T: std::str::FromStr>(tokens: &mut I) -> T {
    tokens.next().unwrap().parse().ok().unwrap()
}

fn main() {
    let input = read_stdin();
    let tokens = &mut input.split_whitespace();
    let n: usize = scan(tokens);
    let q: Vec<usize> = {
        let mut q = vec![0; n + 1];
        for i in 1..n + 1 {
            let p: usize = scan(tokens);
            q[p] = i;
        }
        q
    };
    let mut ans = 0;
    let mut set = None;
    for p in (1..n + 1).rev() {
        let i = q[p];
        let j1 = max_less_than(&set, i).unwrap_or(0);
        let j2 = max_less_than(&set, j1).unwrap_or(0);
        let k1 = min_more_than(&set, i).unwrap_or(n + 1);
        let k2 = min_more_than(&set, k1).unwrap_or(n + 1);
        ans += p * (j1 - j2) * (k1 - i);
        ans += p * (i - j1) * (k2 - k1);
        set = insert(set, i);
    }
    println!("{}", ans);
}

enum Node {
    Leaf(usize),
    Node2(usize, usize, Box<Node>, Box<Node>),
    Node3(usize, usize, Box<Node>, Box<Node>, Box<Node>),
}

impl Node {
    fn min(&self) -> usize {
        match self {
            &Node::Leaf(x) => x,
            &Node::Node2(x, _, _, _) => x,
            &Node::Node3(x, _, _, _, _) => x,
        }
    }
    fn max(&self) -> usize {
        match *self {
            Node::Leaf(x) => x,
            Node::Node2(_, x, _, _) => x,
            Node::Node3(_, x, _, _, _) => x,
        }
    }
}

fn leaf(x: usize) -> Box<Node> {
    Box::new(Node::Leaf(x))
}

fn node2(n1: Box<Node>, n2: Box<Node>) -> Box<Node> {
    Box::new(Node::Node2(n1.min(), n2.max(), n1, n2))
}

fn node3(n1: Box<Node>, n2: Box<Node>, n3: Box<Node>) -> Box<Node> {
    Box::new(Node::Node3(n1.min(), n3.max(), n1, n2, n3))
}

fn insert(set: Option<Box<Node>>, x: usize) -> Option<Box<Node>> {
    fn rec(node: Box<Node>, x: usize) -> (Box<Node>, Option<Box<Node>>) {
        let node: Node = *node;
        match node {
            Node::Leaf(y) => {
                if x < y {
                    (leaf(x), Some(leaf(y)))
                } else if x == y {
                    (leaf(x), None)
                } else {
                    (leaf(y), Some(leaf(x)))
                }
            }
            Node::Node2(_, _, n1, n2) => {
                if x < n2.min() {
                    match rec(n1, x) {
                        (n1, None) => (node2(n1, n2), None),
                        (n11, Some(n12)) => (node3(n11, n12, n2), None),
                    }
                } else {
                    match rec(n2, x) {
                        (n2, None) => (node2(n1, n2), None),
                        (n21, Some(n22)) => (node3(n1, n21, n22), None),
                    }
                }
            }
            Node::Node3(_, _, n1, n2, n3) => {
                if x < n2.min() {
                    match rec(n1, x) {
                        (n1, None) => (node3(n1, n2, n3), None),
                        (n11, Some(n12)) => (node2(n11, n12), Some(node2(n2, n3))),
                    }
                } else if x < n3.min() {
                    match rec(n2, x) {
                        (n2, None) => (node3(n1, n2, n3), None),
                        (n21, Some(n22)) => (node2(n1, n21), Some(node2(n22, n3))),
                    }
                } else {
                    match rec(n3, x) {
                        (n3, None) => (node3(n1, n2, n3), None),
                        (n31, Some(n32)) => (node2(n1, n2), Some(node2(n31, n32))),
                    }
                }
            }
        }
    }
    match set {
        None => Some(leaf(x)),
        Some(node) => match rec(node, x) {
            (node, None) => Some(node),
            (n1, Some(n2)) => Some(node2(n1, n2)),
        },
    }
}

fn max_less_than(set: &Option<Box<Node>>, x: usize) -> Option<usize> {
    fn rec(node: &Box<Node>, x: usize) -> Option<usize> {
        match **node {
            Node::Leaf(y) => {
                if y < x {
                    Some(y)
                } else {
                    None
                }
            }
            Node::Node2(_, _, ref n1, ref n2) => {
                if x <= n1.min() {
                    None
                } else if x <= n2.min() {
                    rec(n1, x)
                } else {
                    rec(n2, x)
                }
            }
            Node::Node3(_, _, ref n1, ref n2, ref n3) => {
                if x <= n1.min() {
                    None
                } else if x <= n2.min() {
                    rec(n1, x)
                } else if x <= n3.min() {
                    rec(n2, x)
                } else {
                    rec(n3, x)
                }
            }
        }
    }
    match set.as_ref() {
        None => None,
        Some(node) => rec(node, x),
    }
}

fn min_more_than(set: &Option<Box<Node>>, x: usize) -> Option<usize> {
    fn rec(node: &Box<Node>, x: usize) -> Option<usize> {
        match **node {
            Node::Leaf(y) => {
                if y > x {
                    Some(y)
                } else {
                    None
                }
            }
            Node::Node2(_, _, ref n1, ref n2) => {
                if x >= n2.max() {
                    None
                } else if x >= n1.max() {
                    rec(n2, x)
                } else {
                    rec(n1, x)
                }
            }
            Node::Node3(_, _, ref n1, ref n2, ref n3) => {
                if x >= n3.max() {
                    None
                } else if x >= n2.max() {
                    rec(n3, x)
                } else if x >= n1.max() {
                    rec(n2, x)
                } else {
                    rec(n1, x)
                }
            }
        }
    }
    match set.as_ref() {
        None => None,
        Some(node) => rec(node, x),
    }
}