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: Accepted)

use std::io::{stdin, Read, StdinLock};
use std::str::FromStr;
use std::cmp::{max, min};

fn main() {
    let cin = stdin();
    let mut scan = Scanner::new(cin.lock());
    let n = scan.read::<usize>();
    let mut l = scan.readn::<i64>(n);
    l.sort();
    let mut ret = 0;
    for i in 0..n {
        for j in i+1..n {
            let a = l[i];
            let b = l[j];
            let d = binary_search(&l, |&c| a < b + c);
            let d2 = binary_search(&l, |&c| b < c + a);
            let e = binary_search_r(&l, |&c| c < a + b);
//            dbg!((d, d2, e));
            let g = max(max(d, d2), j+1);
            let ef = if e + 1 - g > 0 {e + 1 - g} else {0};
//            dbg!(&ef);
            ret += ef;
        }
    }
    println!("{}", ret);
}

#[allow(dead_code)]
fn binary_search<T, F>(arr: &[T], f: F) -> usize where F: Fn(&T) -> bool {
    let mut ok = arr.len() as i64;
    let mut ng = -1i64;
    while (ok - ng).abs() > 1 {
        let mid = (ok + ng) / 2;
        if f(&arr[mid as usize]) {
            ok = mid;
        } else {
            ng = mid;
        }
    }
    ok as usize
}

#[allow(dead_code)]
fn binary_search_r<T, F>(arr: &[T], f: F) -> usize where F: Fn(&T) -> bool {
    let mut ng = arr.len() as i64;
    let mut ok = -1i64;
    while (ok - ng).abs() > 1 {
        let mid = (ok + ng) / 2;
        if f(&arr[mid as usize]) {
            ok = mid;
        } else {
            ng = mid;
        }
    }
    ok as usize
}

// region template
#[allow(dead_code)]
fn iu(i: i64) -> usize { i as usize }

#[allow(dead_code)]
fn ui(i: usize) -> i64 { i as i64 }

#[allow(dead_code, deprecated)]
fn join<T: std::fmt::Display>(slice: &[T], sep: &str) -> String {
    let strings = slice.iter().map(|t| format!("{}", t)).collect::<Vec<_>>();
    strings.connect(sep)
}

#[allow(dead_code)]
fn arr<'a, S, T>(n: usize, mut f: S) -> Vec<T> where S: FnMut(usize) -> T + 'a {
    (0..n).map(|i| f(i)).collect::<Vec<T>>()
}

struct Scanner<'a> {
    cin: StdinLock<'a>,
}

#[allow(dead_code)]
impl<'a> Scanner<'a> {
    fn new(cin: StdinLock<'a>) -> Scanner<'a> {
        Scanner { cin: cin }
    }

    fn read1<T: FromStr>(&mut self) -> Option<T> {
        let token = self.cin.by_ref().bytes().map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<String>();
        token.parse::<T>().ok()
    }

    fn read<T: FromStr>(&mut self) -> T {
        self.read1().unwrap()
    }

    fn readn<T: FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read::<T>()).collect()
    }

    fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}
// endregion