Cod sursa(job #58249)

Utilizator MariusMarius Stroe Marius Data 4 mai 2007 20:33:32
Problema Oite Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 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  1048576 

int C;

int L;

int A[MAX_N];

int num1[MAX_N], cnt1[MAX_N], size1;

int num2[MAX_S], cnt2[MAX_S], size2;

int temp[MAX_S];


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

void f(int num[], int cnt[], int & size)
{
	int j = 0;

	sort(num, num + size);
	temp[0] = num[0];
	cnt[0]  = 1;
	for (int i = 1; i < size; ++ i) {
		if (num[i] != num[i - 1])
			temp[++ j] = num[i];
		cnt[j] ++;		
	}
	size = j + 1;
	memcpy(num, temp, MAX_S << 2);
}

int g(int num[], int cnt[], int size, int key)
{
	int k;
	int stp;
	for (stp = 1; stp < size; stp <<= 1);
	for (k = 0; stp; stp >>= 1) {
		if (k + stp < size && num[k + stp] <= key)
			k += stp;
	}
	if (num[k] == key)
		return cnt[k];
	else
		return 0;
}

int main(void)
{
	freopen(iname, "r", stdin);
	read_in();

	i64 ans = 0;

	for (int i = 0; i < C; ++ i) {
		if (A[i] <= L)
			num1[size1 ++] = A[i];

		for (int j = i + 1; j < C; ++ j)
			if (A[i] + A[j] <= L)
				num2[size2 ++] = A[i] + A[j];
	}
	f(num1, cnt1, size1);
	f(num2, cnt2, size2);

	for (int i = 0; i < C - 1; ++ i) {
		for (int j = i + 1; j < C; ++ j) {
			int sum = L - A[i] - A[j];
			if (sum >= 0) {
				ans += (i64)g(num2, cnt2, size2, sum);
				if (sum == A[i] + A[j])
					ans --;
				if (sum >= A[i]) {
					ans -= (i64)g(num1, cnt1, size1, sum - A[i]);
					if (sum - A[i] == A[j])
						ans ++;
					if (sum - A[i] == A[i])
						ans ++;
				}
				if (sum >= A[j]) {
					ans -= (i64)g(num1, cnt1, size1, sum - A[j]);
					if (sum - A[j] == A[i])
						ans ++;
					if (sum - A[j] == A[j])
						ans ++;
				}
			}
		}
	}
	freopen(oname, "w", stdout);
	printf("%lld\n", ans / 6);

	return 0;
}