Pagini recente » Cod sursa (job #2312617) | Cod sursa (job #558301) | Cod sursa (job #740753) | Cod sursa (job #2042673) | Cod sursa (job #1764794)
#include <stdio.h>
#define nmax ( 1 << 20 )
#define mod 702113
unsigned int v[nmax+1]; ///valorile initiale
unsigned int val[2][nmax]; ///valorile adaugate pe parcurs in lista
int next[2][nmax+1]; ///parcurerea listei
int frecv[2][nmax+1]; ///frecventa unui element in lista
int lasthash[2][mod]; ///ultimul nr cu acel cod hash
int poz, size, n, start, stop, ver;
int caut( unsigned int nr ){
unsigned int h = nr % mod;
int pozcaut = lasthash[ver][h];
while( pozcaut!=0 && val[ver][pozcaut]!=nr ) ///cat timp nu am gasit elementul
pozcaut = next[ver][pozcaut];
return pozcaut; ///daca nu e gasit retunam 0, altfel returnam pozitia sa
}
void insert( unsigned int nr ){
int pozinsert = caut( nr ); ///caut daca a mai fost introdus
unsigned int h = nr % mod;
if( pozinsert!=0 && frecv[ver][pozinsert]!=0 ) ///daca a mai fost introdus, incrementam frecventa
frecv[ver][pozinsert]++;
else{ ///daca este porima oara
val[ver][++poz] = nr; ///adaugam in lista simplu inlantuita
next[ver][poz] = lasthash[ver][h];
lasthash[ver][h] = poz;
frecv[ver][poz] = 1; ///apare prima data
size++; ///inca un element distinct
}
}
void sterge( unsigned int nr ){
unsigned int h = nr % mod;
int pozsters = lasthash[ver][h]; ///initializam cu capul listei
if( val[ver][pozsters]==nr ){ ///daca e chiar capul
frecv[ver][pozsters]--; ///decrementam nr aparitii
if( frecv[ver][pozsters]==0 ){ ///daca am ajuns la 0 scoatem elementul din lista
lasthash[ver][h] = next[ver][pozsters];
size--; ///si decrementa numarul de elemente distincte din secventa
}
}
else{ ///daca nu e la capul listei
while( val[ver][ next[ver][pozsters] ]!=nr && next[ver][pozsters]!=0 ) ///parcurgem lista
pozsters = next[ver][pozsters];
if( val[ver][ next[ver][pozsters] ]==nr ){ ///daca l-am gasit
frecv[ver][ next[ver][pozsters] ]--; ///decrementam nr aparitii
if( frecv[ver][ next[ver][pozsters] ] == 0 ){ ///daca am ajuns la 0 scoatem elementul din lista
size--; ///si decrementa numarul de elemente distincte din secventa
next[ver][pozsters] = next[ver][ next[ver][pozsters] ];
}
}
}
}
long long lung( int max ){
poz = size = 0;
int pozst = 0;
long long co = 0LL;
int i;
for( i=0; i<n; i++ ){ ///parcurgem elementele
insert( v[i] ); ///le adaugam
while( size > max ){ ///in momentul in care depasim limita stergem elementele de inceput ale secventei
sterge( v[pozst] );
pozst++;
}
co += i - pozst + 1; ///contor ce retine nr de secvente; +1 => identat de la 0
}
return co;
}
int main()
{
long long co;
int i;
FILE *fin, *fout;
fin = fopen( "secv5.in", "r" );
fscanf( fin, "%d%d%d", &n, &start, &stop );
for( i=0; i<n; i++ ) ///citesc elementele
fscanf( fin, "%u", &v[i] );
fclose( fin );
ver = 0;
///nr de secvente este diferenta dintre nr de secvente maimale si nr secvente minimae
co = lung( stop );
ver = 1;
co -= lung( start - 1 );
fout = fopen( "secv5.out", "w" );
fprintf( fout, "%lld\n", co );
fclose( fout );
return 0;
}