Cod sursa(job #33175)

Utilizator gcosminGheorghe Cosmin gcosmin Data 18 martie 2007 23:05:12
Problema Oite Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.65 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define NMAX 1030
#define NRB 16
#define JEG 3

int NR;
int mx;

int N, L;

int a[NMAX];

int hash[1 << (NRB + 1)][JEG];
int nsum[1 << (NRB + 1)][JEG];
char jeg[1 << (NRB + 1)][JEG];
int nr[1 << (NRB + 1)];

inline void insert_hash( int sum, int tip)
{
	int i;
	int hs = ((unsigned int) sum * NR) >> (32 - NRB);

	for (i = 0; i < nr[hs]; i++) if (hash[hs][i] == sum && jeg[hs][i] == tip) break;

	if (i < nr[hs]) {
		nsum[hs][i]++;
		return;
	}

	hash[hs][nr[hs]] = sum;
	nsum[hs][nr[hs]] = 1;
	jeg[hs][nr[hs]] = tip;
	nr[hs]++;
	if (nr[hs] > mx) mx = nr[hs];
}

inline int srch(int sum, int tip)
{
	int hs = ((unsigned int) sum * NR) >> (32 - NRB);

	int i;
	for (i = 0; i < nr[hs]; i++) if (hash[hs][i] == sum && jeg[hs][i] == tip) return nsum[hs][i];
	
	return 0;
}

int main()
{
	int i, j, s;
	
	freopen("oite.in", "r", stdin);
	freopen("oite.out", "w", stdout);

	scanf("%d %d", &N, &L);

	for (i = 1; i <= N; i++) scanf("%d", &a[i]);

	int e = 0;
	while (!e) {
		e = 1;
		memset(nr, 0, sizeof(nr));

		NR = (unsigned int) rand() | 1;

		for (i = 1; i <= N; i++) insert_hash(a[i], 0);

		for (i = 1; i <= N && e; i++)
			for (j = i + 1; j <= N && e; j++) {
				if (i == j) continue;

				insert_hash(a[i] + a[j], 1);
				if (mx == JEG) e = 0;
			}
	}

	long long rez = 0;

	for (i = 1; i <= N; i++) 
		for (j = i + 1; j <= N; j++) {
			s = a[i] + a[j];

			rez += srch(L - s, 1);

			rez -= srch(L - s - a[i], 0);
			if (a[i] == L - s - a[i]) rez++;
			rez -= srch(L - s - a[j], 0);
			if (a[j] == L - s - a[j]) rez++;
			
			if (2 * s == L) rez++;
		}

	printf("%lld\n", rez / 6);

fclose(stdin);
fclose(stdout);
return 0;
}