Pagini recente » Cod sursa (job #863997) | Cod sursa (job #106769) | Cod sursa (job #2791289) | Cod sursa (job #1479853) | Cod sursa (job #1302983)
#include <fstream>
using namespace std;
ifstream fin("secv5.in");
ofstream fout("secv5.out");
#define MOD 666013
int v[(1<<20)+1],freq[(1<<20)+1],freq2[(1<<20)+1];
int N,L,U,st,st2,l,nr,nr2,current; //st- punctul de start ale celei mai lungi subsecvente ce se termina in punctul fixat l care are intre L si U elemente distincte
//st2- punctul de start (+1) ale celei mai scurte subsecvente ce se termina in punctul fixat l care are intre L si U elemente distincte
// deoarece pe st2 il avansam cu o casuta ^ atunci st2-st este numarul total de subsecvente care se termina in punctul fixat l si au intre L si U elemente distincte, suma acestora pentru fiecare l ne da solutia
long long total;
struct node
{
unsigned int x;
int norm;
node *next;
}*h[MOD]; //elementele sunt in intervalul [1,2^32] dar numarul lor este in intervalul [1,2^20]. Le normalizam valorile cu o tabela hash
int hash_search (unsigned int x)
{
int j=x%MOD;
for (node *d=h[j]; d!=NULL; d=d->next)
{
if (d->x==x) return d->norm;
}
return 0;
}
void hash_add (unsigned int x, int norm)
{
int j=x%MOD;
node *d= new node;
d->x=x;
d->norm=norm;
d->next=h[j];
h[j]=d;
}
void remove_elem (int &st, int &nr, int freq[])
{
freq[v[st]]--;
if (freq[v[st]]==0) nr--;
st++;
}
void add (unsigned int x)
{
int val= hash_search (x);
if (val) v[l]=val;
else {++current; v[l]=current; hash_add (x,current);}
freq[v[l]]++; freq2[v[l]]++;
if (freq[v[l]]==1) nr++;
if (freq2[v[l]]==1) nr2++;
while (nr2 >= L && st2<=l) remove_elem (st2,nr2,freq2);
}
int main()
{
unsigned int x;
fin>>N>>L>>U;
for (st=1, st2=1 ,l=1; l<=N; l++)
{
fin>>x;
add (x);
while ( nr > U && st<=l) remove_elem (st,nr,freq);
if (nr >= L) total += st2-st;
}
fout<<total;
}