Cod sursa(job #9697)

Utilizator m_dersidanDersidan Mihai m_dersidan Data 27 ianuarie 2007 16:43:34
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Unirea 2007, clasele 11-12 Marime 2.04 kb
# include <stdio.h>

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

# define  maxn  1048776
// # define  prime 551231
# define prime 1051079


typedef struct nod
{
	int x, freq;
	nod *next;
}	*pnod;


pnod hu[prime], hl[prime];
int a[maxn], n, l, u;
long long sol;


void readf()
{
	freopen(_fin, "r", stdin);
	int i;
	for (scanf("%d %d %d", &n, &l, &u), i=1; i<=n; i++)
		 scanf("%d", a+i);
}

int delh(int x, pnod h[prime])
{
	pnod p;
	int to=x % prime;
	
	for (p=h[to]; p; p=p->next)
	   if (p->x == x)
	       break;

    // if (!p) fprintf(stderr, "Warning!\n"), getch();
    p->freq--;
	if ( p->freq==0 ) return 1;	// am scos
	return 0;	// nu am scos nimic
}

int inserth(int x, pnod h[prime])
{
	int to = x % prime;
	pnod p = NULL;

	// caut daca exista
    if ( h[to] )
	   for (p=h[to]; p && p->x != x; p=p->next);
	
    if ( p && p->x == x )
	{
		p->freq++;
		if ( p->freq==1 )
			return 1;	// am inserat
		else
			return 0;	// nu am inserat nimic
	}
	else
	{
		if ( !h[to] )
		{
			h[to] = new nod; 
			h[to]->x = x,
			h[to]->freq=1;
		}
		else
		{
			pnod r = new nod;
			r->x = x, r->freq=1, r->next=h[to], h[to]=r;
		}
		return 1;
	}
}

void solve()
{
	int i, pozU, pozL, difU, difL;
	
	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 += inserth(a[i], hu);
		difL += inserth(a[i], hl);
		
		if ( difL >= l )
		{
			while ( difL >= l )	// avem prea multe
			{
				difL -= delh(a[pozL], hl);
				pozL++;
			}
			--pozL;
			difL += inserth(a[pozL], hl);
		}
		
		while ( difU > u )
		{
			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;
}