Cod sursa(job #10301)

Utilizator MariusMarius Stroe Marius Data 28 ianuarie 2007 10:48:45
Problema Secventa 5 Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <cstdio>
#include <memory>
using namespace std;

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

#define MAX_N   1048576
#define MAX_BUF 11000000
#define MAX_V   65536

typedef unsigned int u32;

int N, L, U;

u32 X[MAX_N];

u32 A[MAX_N], B[MAX_N];

int P[MAX_N];

int cnt[MAX_V], cntL[MAX_N], cntU[MAX_N];

int log;

char buffer[MAX_BUF];

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

void sort(u32 A[], u32 B[], const int k)
{
	int i;
	u32 index;
	memset(cnt, 0, sizeof(cnt));
	for (i = 0; i < N; ++i)
		cnt[(X[ A[i] ] >> (k * 16)) & 65535] ++;
	for (i = 1; i < MAX_V; ++i)
		cnt[i] += cnt[i - 1];
	for (i = N; i--; ) {
		index = ((X[ A[i] ] >> (k * 16)) & 65535);
		B[-- cnt[index]] = A[i];
	}
}

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

int main(void) 
{
	read_in();
	int i;
	int k;
	int FL, numL = 0;
	int FU, numU = 0;
	long long Res = 0;
	for (i = 0; i < N; ++i)
		B[i] = i;
	sort(B, A, 0);
	sort(A, B, 1);
	for (i = 0; i < N; ++i)
		A[i] = X[ B[i] ];
	for (log = 1; log < N; log <<= 1) 
		;	
	for (i = FU = FL = 0; i < N; ++i) {
		P[i] = k = search(X[i]);
		cntL[k] ++;
		if (cntL[k] == 1)
			numL ++;
		cntU[k] ++;
		if (cntU[k] == 1)
			numU ++;
		for (; numU > U; ++FU) {
			k = P[FU];
			cntU[k] --;
			if (cntU[k] == 0)
				numU --;
		}
		for (; numL >= L; ++FL) {
			k = P[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;
}