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

#include <stdio.h>

#define MAX_N 2000
#define MAX_L 1000

int n;
int ls[MAX_N];
int ms[MAX_L+1];

void sort(int n) {
    for (int i = 0; i < n; i++) {
        ms[ls[i]]++;
    }

    int i = 1;
    int j = 0;
    while (i < MAX_L+1) {
        while (ms[i] > 0) {
            ls[j++] = i;
            ms[i]--;
        }
        i++;
    }
}

/*
 * Return the minimum index whose value is same or larger than the target value if exists, otherwise -1.
 *
 * l: lowest index
 * h: highest index
 * x: target value
 */
int search(int l, int h, int x) {
    if (ls[l] >= x) {
        return l;
    }

    while (h - l > 0) {
        // printf("h: %d, l: %d, mid: %d, v: %d\n", h, l, (l + h) / 2, ls[(l + h / 2)]);

        int mid = (l + h) / 2;
        if (ls[mid] < x) {
            l = mid + 1;
        } else if (ls[mid] > x) {
            h = mid;
        } else {
            h = mid;
        }
    }

    if (ls[l] < x) {
        return -1;
    }

    return l;
}

int solve(int n) {
    int count = 0;

    for (int i = n-1; i > 0; i--) {
        for (int j = i-1; j > 0; j--) {
            int a = ls[i];
            int b = ls[j];
            int min_c = a - b + 1;
            int lim_ind = search(0, j-1, min_c);
            // printf("%d %d %d\n", 0, j-1, lim_ind);
            if (lim_ind < 0) {
                break;
            }
            count += j - lim_ind;
        }
    }

    return count;
}

int main(void) {
    scanf("%d\n", &n);

    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        ls[i] = x;
    }

    sort(n);

    // for (int i = 0; i < n; i++) {
    //     printf("%d ", ls[i]);
    // }
    // printf("\n");

    // printf("%d\n", search(0, n, 5));

    printf("%d\n", solve(n));

    return 0;
}