Cod sursa(job #24390)

Utilizator m_dersidanDersidan Mihai m_dersidan Data 2 martie 2007 10:53:22
Problema Secventa 5 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
# include <stdio.h>

# define  _fin  "secv5.in"
# define  _fout "secv5.out"

# define  maxn  1049000
# define  prim  104999


typedef struct nod
{
	unsigned x, v;	// numarul / valoarea
	nod *next;
}	*pnod;

pnod hash[prim];
unsigned  crt;

unsigned found(unsigned x)
{
	pnod q;
	for (q=hash[ x%prim ]; q && q->x != x; q=q->next);
	
	if ( !q ) return 0;
	return q->x==x ? q->v : 0;
}
unsigned insert(unsigned x)
{
	unsigned res, cr=x%prim;
	if ( res=found(x) ) return res;	// must not insert it
	
	if ( !hash[cr] )
		hash[cr]=new nod, hash[cr]->x=x, hash[cr]->v=++crt, hash[cr]->next=NULL;
	else
	{
		pnod l, r;
		for (l=hash[cr]; l->next; l=l->next);
		r = new nod, r->x=x, r->v=++crt, l->next=r, r->next=NULL;
	}

	return crt;
}

unsigned n, l, u, a[maxn], hl[maxn], hu[maxn];
long long sol;

void readf()
{
	freopen(_fin, "r", stdin);
	unsigned i, x, j;
	char buf[12];
	
	for (scanf("%u%u%u", &n, &l, &u), i=1; i<=n; i++)
	{
		scanf("%s\n", buf), x=0;
		for (j=0; buf[j]; j++) x=x*10+buf[j]-0x30;
		a[i] = insert(x);
	}
//		 scanf("%u", &x), a[i]=insert(x);
}

void solve()
{
	unsigned i, pozU, pozL, difU, difL;
	
	hl[ a[1] ] = hu[ a[1] ] = 1;
	// inserth(a[1], hl);
	// inserth(a[1], hu);
	difU=difL=1;	// numarul de elemente distincte din primul / al doilea hash
	pozL=pozU=1;	// pozitiile de inceput
	
	if ( l == 1 ) ++sol;

	for (i=2; i<=n; i++)
	{
		// inserez in amandoua hash-urile
		difU += !hu[ a[i] ], ++hu[ a[i] ];
		//difU += inserth(a[i], hu);
		difL += !hl[ a[i] ], ++hl[ a[i] ];
		//difL += inserth(a[i], hl);
		
		if ( difL >= l )
		{
			while ( difL >= l )	// avem prea multe
			{
				difL -= ( hl[ a[pozL] ]==1 ), --hl[ a[pozL] ];
				// delh(a[pozL], hl);
				pozL++;
			}
			--pozL;
			difL += !hl[ a[pozL] ], ++hl[ a[pozL] ];
			// difL += inserth(a[pozL], hl);
		}
		
		while ( difU > u )
		{
			difU -= ( hu[ a[pozU] ] == 1 ), --hu[ a[pozU] ];
			// difU -= delh(a[pozU], hu);
			pozU++;
		}
		
		if ( difL>=l )
			sol += ( (long long)pozL-(long long)pozU+1 );
	}
}

void writef()
{
	freopen(_fout, "w", stdout);
	printf("%lld\n", sol);
}

int main()
{
	readf();
	solve();
	writef();

	return 0;
}