Cod sursa(job #9506)

Utilizator MariusMarius Stroe Marius Data 27 ianuarie 2007 15:55:17
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Unirea 2007, clasele 11-12 Marime 2.27 kb
#include <cstdio>
using namespace std;

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

#define MAX_N   1050000
#define MAX_BUF 11000000

typedef unsigned int u32;

int N, L, U;

u32 X[MAX_N];

u32 A[MAX_N];

u32 H[MAX_N];

int cntL[MAX_N], cntU[MAX_N], size;

int log;

char buffer[MAX_BUF];

void down(u32 H[], u32 z)
{
	u32 l, r, k;
	for (int done = 0; !done; ) {
		done = 0;
		l = z * 2;
		r = z * 2 + 1;
		k = z;
		if ((l <= H[0]) && (H[l] < H[k]))
			k = l;
		if ((r <= H[0]) && (H[r] < H[k]))
			k = r;
		if (k != z)
			H[k] ^= H[z] ^= H[k] ^= H[z], z = k;
		else
			done = 1;
	}
}

void insert(u32 H[], const u32 num)
{
	u32 k;
	for (k = (++ H[0]); (k > 1) && (H[k >> 1] > num); k >>= 1)
		H[k] = H[k >> 1];
	H[k] = num;
}

u32 getmin(u32 H[])
{
	u32 num = H[1];
	H[1] = H[H[0] --];
	if (H[0] > 1)
		down(H, 1);
	return num;
}

void read_in(void)
{
	freopen(iname, "r", stdin);
	scanf("%d %d %d\n", &N, &L, &U);
	int len = int(fread(buffer, sizeof(char), MAX_BUF, stdin));
	char *p = buffer;
	char *lim = buffer + len;
	for (int i = 0; i < N; ++i) {
		u32 num = 0;
		for (; (p < lim) && (*p) <  '0'; ++p) ;
		for (; (p < lim) && (*p) >= '0'; ++p)
			num = num * 10 + (u32)((*p) - '0');
		X[i] = num;
		insert(H, num);
	}
	for (int i = 0; H[0] > 0; ) {
		A[i] = getmin(H);
		if ((i == 0) || (A[i - 1] != A[i]))
			i ++;
	}
	size = i;
}

int search(const u32 num)
{
	int k;
	int stp = log;
	for (k = 0; stp; stp >>= 1) {
		if ((k + stp < size) && (A[k + stp] <= num))
			k += stp;
	}
	return k;
}

int main(void) 
{
	read_in();
	for (log = 1; log < size; log <<= 1) ;
	int i;
	int k;
	int FL, numL = 0;
	int FU, numU = 0;
	long long Res = 0;
	for (i = FU = FL = 0; i < N; ++i) {
		k = search(X[i]);
		cntL[k] ++;
		if (cntL[k] == 1)
			numL ++;
		cntU[k] ++;
		if (cntU[k] == 1)
			numU ++;
		for (; numU > U; ++FU) {
			k = search(X[FU]);
			cntU[k] --;
			if (cntU[k] == 0)
				numU --;
		}
		for (; numL >= L; ++FL) {
			k = search(X[FL]);
			if ((cntL[k] == 1) && (numL == L))
				break ;
			cntL[k] --;
			if (cntL[k] == 0)
				numL --;
		}
		if (L == numL)
			Res += (long long)(FL - FU + 1);
	}
	freopen(oname, "w", stdout);
	printf("%lld\n", Res);
	return 0;
}