Pagini recente » Cod sursa (job #1310098) | Cod sursa (job #219323) | Cod sursa (job #2960068) | Cod sursa (job #1050558) | Cod sursa (job #1733146)
#include <fstream>
#include <vector>
using namespace std ;
ifstream f("heapuri.in") ;
ofstream g("heapuri.out") ;
int n , tip , x ;
vector <int> heap ; int lg_heap ;
vector <int> V ; int nr_inserari ;
vector <int> Poz ;
int prim ( int x )
{
if ( x < 2 ) return 0 ;
if ( x < 4 ) return 1 ;
if ( x % 2 == 0 ) return 0 ;
for ( int d = 3 ; d * d <= x ; d += 2 )
if ( x % d == 0 )
return 0 ;
return 1 ;
}
void promovare ( int k )
{
//promoveaza pe h[k] in heap
int este_heap = 0 ;
while ( este_heap == 0 ) //cat timp nu este heap
{
if ( k == 1 ) //daca am ajuns in radacina , cu siguranta a ajuns heap
este_heap = 1 ;
else
{
if ( V[heap[k/2]] < V[heap[k]] ) //daca tatal sau este mai mic /egal cu el , atunci se respecta proprietatea de min-heap
este_heap = 1 ;
else //altfe trebuie sa schimbam cele doua pozitii si sa "avansam" in sus
{
swap ( heap[k] , heap[k/2] ) ; //schimbam pozitiile ( valorile raman in V )
//schimbam si pozitiile cronologie
Poz[heap[k]] = k ;
Poz[heap[k/2]] = k / 2 ;
k /= 2 ; //avansam in ierarhie
}
}
}
}
void cernere ( int k )
{
//il coboram pe h[k] in heap pana cand se intampla conditia
int este_heap = 0 ;
while ( este_heap == 0 )
{
if ( 2*k > lg_heap ) //nu mai are fii cu care sa se compare
este_heap = 1 ;
else
{
int i = 2 * k ;
if ( i + 1 <= n ) //daca are si fiu drept
if ( V[heap[i+1]] < V[heap[i]] )
++i ; //il alegem pe cel mai mic sa ii schimbam
if ( V[heap[i]] < V[heap[k]] )
{
swap ( heap[i] , heap[k] ) ;
Poz[heap[i]] = i ;
Poz[heap[k]] = k ;
k = i ;
}
else
este_heap = 1 ;
}
}
}
int main ()
{
f >> n ;
V.resize ( n + 1 ) , heap.resize ( n + 1 ) , Poz.resize ( n + 1 ) ;
for ( int i = 1 ; i <= n ; ++i )
{
f >> tip ;
if ( tip == 1 ) //avem operatie de inserare
{
f >> V[++nr_inserari] ; //citim numarul si il punem in sirul de numere citite
heap[++lg_heap] = nr_inserari ; //in heap adaugam pozitia numarului din V , nu numarul la capatul heapului
Poz[nr_inserari] = lg_heap ; //Poz[x] marcheaza pozitia celui de-al x numar inserat in heap
promovare(lg_heap) ;
}
if ( tip == 2 ) //avem operatie de stergere
{
int x ;
f >> x ;
//facem elementul acela de valoare mica ( negativa ) , apoi il promovam , apoi eliminam apoi trebuie sa reparam heapul
V[x] = -1 ; //negativ ,deci va fi radacina
promovare( Poz[x] ) ; // el se afla in heap la poz[x]
//acum el se afla in radacina ; il eliminam si aducem capatul heapului aici
Poz[heap[1]] = 0 ;
heap[1] = heap[lg_heap--] ; //scade lungimea heapului cu 1
Poz[heap[1]] = 1 ;
cernere ( 1 ) ;
}
if ( tip == 3 )
{
g << V[heap[1]] << "\n" ;
}
}
return 0 ;
}