Cod sursa(job #784238)

Utilizator DEYDEY2Tudorica Andrei DEYDEY2 Data 5 septembrie 2012 12:02:28
Problema Secventa 5 Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.74 kb
#include <stdio.h>
#include <vector>
#define MAX 666013LL
using namespace std;

unsigned int n,L,U,t;
unsigned int S[1000001],i;
unsigned int SN[1000001];
unsigned int nr;
vector <unsigned int> H[MAX];
unsigned int rez,rez1,rez2;
unsigned int LA[1000001];
unsigned int FR[1000001];

unsigned int cauta(unsigned int x)
// functia cauta returneaza 1000000000 daca x nu exista in hash
// altfel returneaza indicele de sir unde apare prima data x
{
	vector <unsigned int> :: iterator it;
	unsigned int v;
	v=x%MAX;
	for (it=H[v].begin();it!=H[v].end();it++)
		if (S[(*it)]==x)
			return (*it);
	return 1000000000;
}

unsigned int f(unsigned int x)
// f returneaza numarul de subsecvente din sirul S
// care au cel mult x valori diferite intre ele
{
	unsigned int rez;
	unsigned int poz;
	unsigned int nr;
	unsigned int i;
	if (x==0)
		return 0;
	LA[1]=1;
	poz=1;
	nr=1;
	for (i=0;i<=1000000;i++)
		FR[i]=0;
	FR[SN[1]]=1;
	for (i=2;i<=n;i++)
	{
		FR[SN[i]]++;
		if (FR[SN[i]]==1)
			nr++;
		if (nr>x)
		{
			while (nr!=x)
			{
				FR[SN[poz]]--;
				if (FR[SN[poz]]==0)
					nr--;
				poz++;
			}
			LA[i]=poz;
		}
		else
			LA[i]=LA[i-1];
	}
	rez=0;
	for (i=1;i<=n;i++)
		rez=rez+(i-LA[i]+1);
	return rez;
}

void adauga(unsigned int i)
{
	unsigned int v;
	v=S[i]%MAX;
	H[v].push_back(i);
}

int main()
{
	freopen("secv5.in","r",stdin);
	freopen("secv5.out","w",stdout);
	scanf("%u%u%u",&n,&L,&U);
	for (i=1;i<=n;i++)
		scanf("%u",&S[i]);
	// normalizarea sirului S
	nr=0;
	for (i=1;i<=n;i++)
	{
		t=cauta(S[i]);
		if (t==1000000000)
		{
			SN[i]=nr;
			nr++;
			adauga(i);
		}
		else
			SN[i]=SN[t];
	}
	rez1=f(U);
	rez2=f(L-1);
	rez=rez1-rez2;
	printf("%u\n",rez);
	return 0;
}