Cod sursa(job #58272)

Utilizator MariusMarius Stroe Marius Data 4 mai 2007 22:21:30
Problema Oite Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

const char iname[] = "oite.in";
const char oname[] = "oite.out";

typedef long long i64;

#define MAX_N  1024
#define MAX_S  523776 

int C;

int L;

int A[MAX_N];

struct entry {
	int sum;
	int x;
	int y;
} ;

entry E[MAX_S], T[MAX_S];	int cnte;

int B[MAX_N], F[MAX_N], cntb, logb;


void read_in(void)
{
	scanf("%d", &C);
	scanf("%d", &L);
	for (int i = 0; i < C; ++ i)
		scanf("%d", &A[i]);
}

void countsort(entry A[], entry B[], int gr)
{
	int cnt[65536] = {0};
	int i;
	int num;
	
	for (i = 0; i < cnte; ++ i) {
		num = gr ? (A[i].sum >> 16) : (A[i].sum & 65535);
		cnt[num] ++;
	}
	for (i = 1; i < 65536; ++ i)
		cnt[i] += cnt[i - 1];
	for (i = cnte; i --; ) {
		num = gr ? (A[i].sum >> 16) : (A[i].sum & 65535);
		B[-- cnt[num]] = A[i];
	}
}

inline int search(const int key)
{
	int k;
	int stp = logb;
	for (k = 0; stp; stp >>= 1) {
		if (k + stp < cntb && B[k + stp] <= key)
			k = k + stp;
	}
	if (B[k] == key)
		return F[k];
	else
		return 0;
}

int main(void)
{
	freopen(iname, "r", stdin);
	read_in();
	
	sort(A, A + C);
	for (int i = 0; i < C; ++ i) {
		if (i > 0 && A[i] != A[i - 1])
			cntb ++;
		B[cntb] = A[i];
		F[cntb] ++;
	}
	cntb ++;
	for (logb = 1; logb < cntb; logb <<= 1) ;
	
	for (int i = 0; i < C; ++ i) {
		for (int j = i + 1; j < C; ++ j) {
			E[cnte].x = i;
			E[cnte].y = j;
			E[cnte ++].sum = A[i] + A[j];
		}
	}
	countsort(E, T, 0);
	countsort(T, E, 1);
	
	i64 ans;
	int lo, hi;
	ans = 0;
	lo  = hi = cnte - 1;
	for (int i = 0; i < cnte; ++ i) {
		int sum = E[i].sum;
		int x = E[i].x;
		int y = E[i].y;
		if (sum > L)
			continue ;
		if (i > 0 && E[i].sum != E[i - 1].sum)
			hi = lo;
		while (lo >= 0 && E[lo].sum >= L - sum)
			-- lo;
		while (hi >= 0 && E[hi].sum >  L - sum)
			-- hi;
		
		ans += (i64)(hi - lo);
		if (lo < i && i <= hi)
			ans --;
	
		ans -= (i64)(search(L - sum - A[x]));
		if (L - sum - A[x] == A[x])
			ans ++;
		
		ans -= (i64)(search(L - sum - A[y]));
		if (L - sum - A[y] == A[y])
			ans ++;

		if (L - sum - A[x] == A[y])
			ans += 2;				
	}
	freopen(oname, "w", stdout);
	printf("%lld\n", ans / 6);

	return 0;
}