Cod sursa(job #2617969)

Utilizator ReksioCroftOctavian Florin Staicu ReksioCroft Data 23 mai 2020 13:45:52
Problema Heapuri Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.5 kb
#include <stdio.h>
#include <assert.h>


#define nmax 200001
struct heap {
    int val, index;
} v[nmax];
int pozHeap, co;
int pozNod[nmax];


void urcareHeap( int poz ) {
    struct heap aux;
    while ( poz > 1 && v[ poz / 2 ].val > v[ poz ].val ) { ///interschimbam elementul cu tatal sau
        pozNod[ v[ poz / 2 ].index ] = poz;
        pozNod[ v[ poz ].index ] = poz / 2;
        aux = v[ poz / 2 ];
        v[ poz / 2 ] = v[ poz ];
        v[ poz ] = aux;
        poz /= 2;
    }
}


void coborareHeap( int poz ) {
    struct heap aux;
    while ( ( poz * 2 <= pozHeap && v[ poz * 2 ].val < v[ poz ].val ) ||
            ( ( poz * 2 + 1 ) <= pozHeap && v[ poz * 2 + 1 ].val < v[ poz ].val ) ) {
        if ( ( poz * 2 == pozHeap && v[ poz * 2 ].val < v[ poz ].val ) ||
             ( poz * 2 < pozHeap && v[ poz * 2 ].val < v[ poz * 2 + 1 ].val ) ) {
            pozNod[ v[ poz * 2 ].index ] = poz;
            pozNod[ v[ poz ].index ] = poz * 2;
            aux = v[ poz * 2 ];
            v[ poz * 2 ] = v[ poz ];
            v[ poz ] = aux;
            poz *= 2;
        }
        else {
            pozNod[ v[ poz * 2 + 1 ].index ] = poz;
            pozNod[ v[ poz ].index ] = poz * 2 + 1;
            aux = v[ poz * 2 + 1 ];
            v[ poz * 2 + 1 ] = v[ poz ];
            v[ poz ] = aux;
            poz = poz * 2 + 1;
        }
    }
}


void inserareHeap( int nr ) {
    pozHeap++;
    co++;
    v[ pozHeap ].val = nr; ///inseram nr pe ultima pozitie in heap
    v[ pozHeap ].index = co;
    pozNod[ co ] = pozHeap;
    urcareHeap( pozHeap );
}


void stergereHeap( int ordinInsertie ) {
    int poz;
    struct heap aux;
    poz = pozNod[ ordinInsertie ];
    pozNod[ v[ pozHeap ].index ] = poz;
    pozNod[ ordinInsertie ] = -1;
    aux = v[ poz ];
    v[ poz ] = v[ pozHeap ];
    v[ pozHeap ] = aux;
    pozHeap--;
    if ( poz > 1 && v[ poz / 2 ].val > v[ poz ].val )
        urcareHeap( poz );
    else
        coborareHeap( poz );
}


int main() {
    int n, i, ver, nr;
    FILE *fin, *fout;
    fin = fopen( "heapuri.in", "r" );
    fout = fopen( "heapuri.out", "w" );
    assert( fscanf( fin, "%d", &n ) == 1 );
    for ( i = 0; i < n; i++ ) {
        assert( fscanf( fin, "%d", &ver ) == 1 );
        if ( ver == 3 )
            fprintf( fout, "%d\n", v[ 1 ].val );
        else {
            assert( fscanf( fin, "%d", &nr ) == 1 );
            if ( ver == 1 )
                inserareHeap( nr );
            else
                stergereHeap( nr );
        }
    }
    fclose( fin );
    fclose( fout );
    return 0;
}