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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using static System.Console;
using System.Runtime.CompilerServices;
using static MyUtil;

class MyUtil
{
    public static int[] ReadIntArray()
    {
	return ReadLine().Split().Select(x => int.Parse(x)).ToArray();
    }
    public static void Swap<T>(ref T a, ref T b)
    {
	var t = a;
	a = b;
	b = t;
    }
}

class Bisect
{
    /* BisectRight(a, x) returns the index where to insert x in a sorted list a.
     * 
     * The return value i is such that for all j < i, a[j] <= x and
     * for all j >= i, a[j] > x.
     */
    public static
	int BisectRight<T>(T[] a, T x, int lo=0, int hi=-1) where T:IComparable
    {
	if (hi < 0)  hi = a.Length;
	while (lo < hi)
	{
	    int mid = (lo + hi) / 2;
	    if (x.CompareTo(a[mid]) < 0) { hi = mid; }
	    else { lo = mid + 1; }
	}
	return lo;
    }
								    
    /* BisectLeft(a, x) returns the index where to insert x in a sorted list a.
     * 
     * The return value i is such that for all j < i, a[j] < x and
     * for all j >= i, a[j] >= x.
     */
    public static
	int BisectLeft<T>(T[] a, T x, int lo=0, int hi=-1) where T:IComparable
    {
	if (hi < 0)  hi = a.Length;
	while (lo < hi)
	{
	    int mid = (lo + hi) / 2;
	    if (a[mid].CompareTo(x) < 0) { lo = mid + 1; }
	    else { hi = mid; }
	}
	return lo;
    }
}

class Program
{
    public static void Main()
    {
	int n = int.Parse(ReadLine());
	int[] L = ReadIntArray();
	Array.Sort(L);

	//for (int i = 0; i < n; i++) Write($"{L[i]} ");
	//WriteLine("");
	
	long ans = 0;
	for (int i = n-1; i >= 2; i--)
	{
	    int a = L[i];
	    for (int j = i-1; j >= 1; j--)
	    {
		int b = L[j];

		int kmax = Bisect.BisectRight(L, a+b, 0, j);
		int kmin = Bisect.BisectRight(L, a-b, 0, j);
		ans += (kmax - kmin);
		
		//WriteLine($"i={i}, j={j}, a={a}, b={b}");
		//WriteLine($"kmax = {kmax}, kmin={kmin}, ans={ans}");
	    }
	}

	WriteLine(ans);
    }
}