Problem:
Score : 400 points

Problem Statement

Takahashi has N sticks that are distinguishable from each other. The length of the i-th stick is L_i.

He is going to form a triangle using three of these sticks. Let a, b, and c be the lengths of the three sticks used. Here, all of the following conditions must be satisfied:

a < b + c

b < c + a

c < a + b

How many different triangles can be formed? Two triangles are considered different when there is a stick used in only one of them.

Constraints

All values in input are integers.

3 \leq N \leq 2 \times 10^3

1 \leq L_i \leq 10^3

Input

Input is given from Standard Input in the following format:

N
L_1 L_2 ... L_N

Constraints

Print the number of different triangles that can be formed.

Sample Input 1

4
3 4 2 1

Sample Output 1

1

Only one triangle can be formed: the triangle formed by the first, second, and third sticks.

Sample Input 2

3
1 1000 1

Sample Output 2

0

No triangles can be formed.

Sample Input 3

7
218 786 704 233 645 728 389

Sample Output 3

23

Solution in Rust (1.15.1) (judge verdict: Time Limit Exceeded)

use std::cmp::min;
use std::io::prelude::*;
use std::io::stdin;
use std::str::FromStr;

fn main() {
    let n: usize = read();
    let mut l: Vec<u64> = (0..n).map(|_| read()).collect();

    let mut count = 0;
    l.sort();

    for i in 0..l.len() {
        for j in 0..i {
            let k_max = l.upper_bound(&(l[i] + l[j] - 1));
            for k in 0..min(k_max, j) {
                if l[k] < l[i] + l[j] && l[i] < l[j] + l[k] && l[j] < l[i] + l[k] {
                    count += 1;
                }
            }
        }
    }

    println!("{}", count);
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let token: String = stdin
        .lock()
        .bytes()
        .map(|b| b.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().unwrap()
}

// like c++ std::lower_bound and std::upper_bound
trait BinarySearch<T: Ord> {
    fn lower_bound(&self, x: &T) -> usize;
    fn upper_bound(&self, x: &T) -> usize;
}

impl<T: Ord> BinarySearch<T> for [T] {
    fn lower_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();
        while low != high {
            let mid = low + (high - low) / 2;
            match self[mid].cmp(x) {
                std::cmp::Ordering::Less => low = mid + 1,
                _ => high = mid,
            }
        }
        low
    }

    fn upper_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();
        while low != high {
            let mid = low + (high - low) / 2;
            match self[mid].cmp(x) {
                std::cmp::Ordering::Greater => high = mid,
                _ => low = mid + 1,
            }
        }
        high
    }
}