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 JavaScript (Node.js 12.16.1) (judge verdict: Accepted)

"use strict"
const create = () => {
    const input = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");
    const res = {
        "list": input, "index": 0, "max": input.length,
        "hasNext": function() {return this.index < this.max},
        "next": function() { if (!this.hasNext()) {throw "ArrayIndexOutOfBoundsException";}else{return this.list[this.index++];}}
    };
    return res;
}
const o = create();
const next = () => o.next()
const nextInt = () => parseInt(o.next())
const nextStrArray = () => o.next().split(" ")
const nextIntArray = () => o.next().split(" ").map(el => parseInt(el))
const nextCharArray = () => o.next().split("")
const hasNext = () => o.hasNext()
const myout = (...x) => console.log(...x)

const bs = (arr, x) => {
    let l = -1
    let r = arr.length
    while(r-l >1){
        let mid = Math.floor((l+r)/2)
        if(arr[mid] >= x){
            r = mid
        }else{
            l = mid
        }
    }
    return r
}

const bs2 = (arr, x) => {
    let l = -1
    let r = arr.length
    while(r-l >1){
        let mid = Math.floor((l+r)/2)
        if(arr[mid] <= x){
            l = mid
        }else{
            r = mid
        }
    }
    return l
}

const Main = () => {
    const n = nextInt()
    let l = nextIntArray()
    l.sort((a,b)=>a-b)
    let cnt = 0
    for(let i = 0; i<l.length-2;i++){
        for(let j = i+1; j < l.length-1; j++){
            const gte = l[j] - l[i] + 1
            const lte = l[j] + l[i] - 1
            let firstIdx = bs(l, gte)
            let lastIdx = bs2(l, lte)
            firstIdx = Math.max(j+1, firstIdx)
            lastIdx = Math.min(l.length, lastIdx)
            if(firstIdx <= lastIdx){
                cnt += lastIdx - firstIdx + 1
            }
        }
    }
    console.log(cnt)
}
Main()