Cod sursa(job #1733146)

Utilizator jurjstyleJurj Andrei jurjstyle Data 23 iulie 2016 18:49:19
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#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 ;
}