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++14 (GCC 5.4.1) (judge verdict: Accepted)

//============================================================================
// Name        : filename.cpp
// Author      : abb
// Version     :
// Copyright   : [My copyright notice]
// Description : test program
//============================================================================

/*
D - Triangles

実行時間制限: 2 sec / メモリ制限: 1024 MB

配点 : 400 点

問題文
高橋君は、互いに区別出来る N 本の棒を持っています。i 本目の棒の長さは L_i です。
高橋君は、これらのうち 3 本の棒を使って三角形を作ろうとしています。このとき、棒の長さを a, b, c として、以下の条件がすべて成り立たなければなりません。

・a < b + c
・b < c + a
・c < a + b

作れる三角形は何種類あるでしょうか。ただし、2 つの三角形は、そのうち一方にのみ使われている棒が存在するときに異なるとします。

制約

・入力は全て整数
・3 ≤ N ≤ 2 × 10^3
・1 <= L_i <= 10^3

 */

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;

#define REP(i, m, n) for (ll i = (m); i < (ll)(n); ++(i))
#define REPM(i, m, n) for (ll i = (m); i <= (ll)(n); ++(i))
#define REPR(i, m, n) for (ll i = (m); i >= (ll)(n); --(i))
#define REPD(i, m, n, d) for (ll i = (m); i < (ll)(n); i += (d))
#define REPMD(i, m, n, d) for (ll i = (m); i <= (ll)(n); i += (d))
#define ALL(x) begin(x), end(x)

/**
 * エントリポイント．
 * @return 0.
 */
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    ll n;
    cin >> n;
    vector<ll> l(n);
    REP(i, 0, n)
    {
        cin >> l[i];
    }
    sort(ALL(l));
    ll count = 0;
    REP(i, 0, n - 1)
    {
        ll l1 = l[i]; // 短い方
        REP(j, i + 1, n)
        {
            ll l2 = l[j];         // 長い方
            ll min = l2 - l1 + 1; // これ以上じゃないといけない
            ll max = l2 + l1 - 1; // これ以下じゃないといけない
            auto left = lower_bound(ALL(l), min);
            auto right = upper_bound(ALL(l), max);
            ll span = distance(left, right); //  right - left;
            if (min <= l1 && l1 <= max)
            {
                span--;
            }
            if (min <= l2 && l2 <= max)
            {
                span--;
            }
            // cerr << l1 << " " << l2 << " " << max << " " << min << " " << span << endl;
            count += span;
        }
    }
    cout << count / 3 << endl; // 3つ分重複してカウントされるので割る
    return 0;
}