Cod sursa(job #13890)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 7 februarie 2007 19:10:02
Problema Secventa 5 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.69 kb
/*
 * Cel putin L - cel putin U + 1 :)
 * this way seems to be a little more simple
 *
 * HASH is BAD, HASH is EVIL
 */

#include <cstdio>
#include <cstdlib>
#include <utility>

using namespace std;

const int NMAX = 1 << 20;
const int HMAX = 3330179;
const int C1 = 30103;
const int C2 = 666013;
const int C3 = 13;

int N, L, U, W;
int A[NMAX], V[NMAX];
pair <unsigned, int> H[HMAX];

void insert(unsigned key, int val) {
	int i = -1, poz;

	do {
		++i;
		poz = ((long long) key * C1 + i * C2 + C3 * i * i) % HMAX;
	} while (H[poz].first != 0);

	H[poz].first = key;
	H[poz].second = val;
}

int find(unsigned key) {
	int i = -1, poz;

	do {
		++i;
		poz = ((long long) key * C1 + i * C2 + C3 * i * i) % HMAX;
	} while (H[poz].first != key && H[poz].first != 0);
	
	return H[poz].first == 0 ? -1 : H[poz].second;
}

void read() {
	FILE *fin = fopen("secv5.in", "rt");
	int i, j, t;
	unsigned aux;
	char buf[16];

	fscanf(fin, " %d %d %d ", &N, &L, &U);

	for (i = 0; fgets(buf, 16, fin) > 0; ++i) {
		
		for (aux = 0, j = 0; buf[j] != '\n'; ++j)
			aux = (aux * 10) + (buf[j] - '0');
		
		t = find(aux);
		
		if (t == -1) 
			insert(aux, W),
			t = W++;

		A[i] = t;
	}

	fclose(fin);
}

long long least(int k) {
	int i, Q;
	int nr = 0;
	long long rez = 0;

	Q = 0;

	for (i = 0; i < N; ++i) {
		++V[A[i]];
		if (V[A[i]] == 1) ++nr;

		while (1) {
			if (nr > k || (nr == k && V[A[Q]] > 1)) {
				--V[A[Q]];
				if (V[A[Q]] == 0) --nr;
				++Q;
			} else break;
		}
		
		if (nr == k) rez += Q + 1;
	}

	for (; Q < N; ++Q) V[A[Q]] = 0;

	return rez;
}

void write() {
	FILE *fout = fopen("secv5.out", "wt");

	fprintf(fout, "%lld\n", least(L) - least(U + 1));

	fclose(fout);
}

int main() {
	
	read();

	write();

	return 0;
}