Cod sursa(job #10332)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 28 ianuarie 2007 12:17:39
Problema Secventa 5 Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.66 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 <cmath>
#include <map>

using namespace std;

#define PB push_back
#define MP make_pair

const int NMAX = 1 << 20;
const int DMAX = 333017;
const double phi = (sqrt(5.) - 1) / 2;

inline int hash(int k) {
	double t = k * phi;
	return (int) (t - (int) t) * DMAX;
}

int N, L, U;
int A[NMAX];
map <int, int> H[DMAX];

map <int, int> :: iterator find(int k, int t) {
	return H[t].find(k);
}

void add(int k, int t) {
	H[t][k] = 1;
}

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

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

	for (i = 0; i < N; ++i) {
		fgets(buf, 16, fin);

		for (aux = 0, j = 0; buf[j] && buf[j] != '\n'; ++j)
			aux = (aux * 10) + (buf[j] - '0');
		
		A[i] = aux;
	}

	fclose(fin);
}

long long least(int k) {
	int i, Q, t;
	map <int, int> :: iterator it;
	int nr = 0;
	long long rez = 0;

	Q = 0;

	for (i = 0; i < N; ++i) {
		t = hash(A[i]);
		it = find(A[i], t);

		if (it == H[t].end())
			add(A[i], t),
			++nr;
		else
			++(*it).second;

		while (1) {
			t = hash(A[Q]);
			it = find(A[Q], t);
			if (nr > k || (nr == k && (*it).second > 1)) {
				--(*it).second; ++Q;
				if ((*it).second == 0) 
					--nr,
					H[t].erase(it);
			} else break;
		}
		
		if (nr == k) rez += Q + 1;
	}

	for (; Q < N; ++Q) {
		t = hash(A[Q]);
		it = find(A[Q], t);
		if (it != H[t].end())
			H[t].erase( it );
	}

	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;
}