Cod sursa(job #784230)

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

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

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

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

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

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