Cod sursa(job #698199)

Utilizator amaliutzzaGoia Amalia amaliutzza Data 29 februarie 2012 12:54:03
Problema Heapuri Scor 0
Compilator fpc Status done
Runda Arhiva educationala Marime 3.46 kb
program heaps2;

type heap=array[1..200000]of longint;

var fi,fo:text;
    h,ord:heap;
    n,nrn,i,op,key,indice,ordi:longint;

//----------------------------------------

      function tata(k:longint):longint;
      begin   tata:=k div 2;        end;

      function fiu_Stg(k:longint):longint;
      begin   fiu_stg:=k*2;           end;

      function fiu_dr(k:longint):longint;
      begin  fiu_dr:=k*2+1;          end;

      procedure swap(var a,b:longint);
      var c:longint;
      begin
          c:=a; a:=b; b:=c;
      end;

//----------------------------------------

    procedure insus(var h:heap; n,k:longint);
    var key:longint;
    begin
      key:=h[k];
        while (k>1) and (key<h[tata(k)]) do
        //cat timp nu am ajuns la radacina
        //si elementul key are o valoare mai mare decat tatal, il
        //"degradez" pe tata
          begin
              h[k]:=h[tata(k)];
              k:=tata(k);
          end;
        h[k]:=key;
    end;

    procedure injos(var h:heap; n,k:longint);
    var fiu:longint;
    begin

    //interschimba mereu nodul cu cel mai mare fiu al sau,
    //daca nodul este mai mic decat un fiu de-al sau

        repeat
          fiu:=0;
          if fiu_stg(k)<n then
            begin
                fiu:=fiu_stg(k);
                if (fiu_dr(k)<=n) and (h[fiu_dr(k)]>h[fiu_stg(k)]) then
                   fiu:=fiu_dr(k);
                //am selectat pozitia celui mai mare fiu al lui k
                //daca fiul ales e mai mic decat k, inseamna ca
                //elementul este pe o pozitie buna

                if h[fiu]>h[k] then
                  fiu:=0;
            end;

          //altfel, inseamna ca fiul trebuie "degradat"
          if fiu<>0 then
            begin
                swap(h[k], h[fiu]);
                k:=fiu;
            end;

        until fiu=0;
    end;

//---------------------------------------------

    procedure sterg(var h:heap; var n:longint; k:longint);
    begin
         h[k]:=h[n]; //pun ultimul element din heap in locul celui pe care il elimin
         if (k>1) and (h[k]<h[tata(k)]) then  //daca nodul pus este mai mare decat tatal sau, il upgradez
            insus(h,n,k)
         else                                //daca este mai mic decat unul din fiii sai
            injos(h,n,k);
    end;





  procedure insert(key:longint);
  begin
      inc(n);
      h[n]:=key;
      inc(ordi);
      ord[ordi]:=key;
      insus(h,n,n);
  end;

//----------------------------------------------

  procedure afisheap;
  var i:longint;
  begin
      for i:=1 to n do
        write(h[i],' ');
  end;

    function cauta(key:longint):longint;
    var i:longint;
    begin
        for i:=1 to n do
          if h[i]=key then
            begin
                cauta:=i;
                exit;
            end;
    end;

//-----------------------------------------------

begin
    assign(fi,'heapuri.in'); reset(fi);
    assign(fo,'heapuri.out'); rewrite(fo);

      readln(fi,nrn);
      for i:=1 to nrn do
        begin
            read(fi,op);
            case op of 1: begin read(fi,key); insert(key); afisheap; writeln; end;
                       2: begin read(fi,key); indice:=ord[key]; indice:=cauta(indice); sterg(h,n,indice); afisheap; writeln; end;
                       3: begin writeln(fo,h[1]); end;
            end;
        end;


      //afisheap;
    close(fi); close(fo);
end.