Cod sursa(job #784225)

Utilizator DEYDEY2Tudorica Andrei DEYDEY2 Data 5 septembrie 2012 11:35:43
Problema Secventa 5 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.61 kb
#include <fstream>
#include <iostream>
#include <vector>
#define MAX 666013
using namespace std;
ifstream fi("secv5.in");
ofstream fo("secv5.out");
int n,L,U,t;
unsigned int S[1000001],i;
unsigned int SN[1000001];
int nr;
vector <int> H[MAX];
unsigned int rez,rez1,rez2;
unsigned int LA[1000001];
unsigned int FR[1000001];

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

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

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

int main()
{
	fi>>n>>L>>U;
	for (i=1;i<=n;i++)
		fi>>S[i];
	// normalizarea sirului S
	nr=-1;
	for (i=1;i<=n;i++)
	{
		t=cauta(S[i]);
		if (t==-1)
		{
			nr++;
			SN[i]=nr;
			adauga(i);
		}
		else
			SN[i]=SN[t];
	}
	rez1=f(U);
	rez2=f(L-1);
	rez=rez1-rez2;
	fo<<rez<<'\n';
	fi.close();
	fo.close();
	return 0;
}