Cod sursa(job #392368)

Utilizator mimarcelMoldovan Marcel mimarcel Data 7 februarie 2010 14:15:27
Problema Heapuri Scor 100
Compilator fpc Status done
Runda Arhiva educationala Marime 2.7 kb
//Algoritmul nu poate fi inteles daca nu se cunoaste notiunea de heap!
const maxn=200000;
type element=record
             nr,poz:longint;
             end;
     heap=array[1..maxn]of element;
     vector=array[1..maxn]of longint;
var h:heap;
    v:vector;
    n,i,x,m,j:longint;
    cod:byte;
{
m - numarul de elemente inserate pana acum
pt 1<=i<=m :
   h[i].nr - numarul din heap de pe pozitia i
   h[i].poz - arata al catele-a a fost inserat in heap
   v[i] - arata pe ce pozitie se afla in heap al i-lea element inserat
     => v[h[i].poz]=i
}

function parinte(a:longint):longint;begin parinte:=a shr 1;end;

procedure sus(a:longint);
var k:element;
    p:longint;
begin
//elementul de pe pozitia a nu este asezat corect in heap (este mai mic decat tatal sau)
//mut elementul de pe pozitia a din heap mai sus, pastrand structura de heap
k:=h[a];
p:=parinte(a);
while(a<>1)and(k.nr<h[p].nr)do
  begin
  h[a]:=h[p];
  v[h[a].poz]:=a;
  a:=p;
  p:=parinte(a);
  end;
h[a]:=k;
v[k.poz]:=a;
end;

procedure insert;
begin//adaug nr x in heap
inc(m);
with h[m] do
  begin
  nr:=x;
  poz:=j;
  end;
sus(m);
end;

function stanga(a:longint):longint;begin stanga:=a shl 1;end;

function dreapta(a:longint):longint;begin dreapta:=a shl 1+1;end;

procedure jos(a:longint);
var k:element;
    f:longint;
begin
//elementul de pe pozitia a nu este asezat corect in heap (este mai mare decat unul dintre fii sai)
//mut elementul de pe pozitia a din heap mai jos, pastrand structura de heap
k:=h[a];
repeat
if stanga(a)>m then break
               else
  begin
  f:=stanga(a);
  if(dreapta(a)<=m)and(h[dreapta(a)].nr<h[f].nr)then f:=dreapta(a);
  end;
if h[f].nr<k.nr then begin
                     v[h[f].poz]:=a;
                     h[a]:=h[f];
                     a:=f;
                     end
                else break;
until false;
h[a]:=k;
v[k.poz]:=a;
end;

procedure sterge;
begin
//sterg al x-lea numar inserat in heap, dar al x-lea element inserat
//  in heap nu este neaparat pe pozitia x in heap, din aceasta cauza
//  am creeat vectorul v pentru care v[x] este pozitia elementului in heap
//  => sterg h[v[x]]
x:=v[x];
h[x]:=h[m];
dec(m);
if x<>m+1 then if(x<>1)and(h[x].nr<h[parinte(x)].nr)then sus(x)
                                                    else jos(x);
end;

begin
assign(input,'heapuri.in');
reset(input);
assign(output,'heapuri.out');
rewrite(output);
readln(n);
m:=0;
j:=0;
for i:=1 to n do
  begin
  read(cod);
  case cod of
    1:begin
      inc(j);
      readln(x);
      insert;
      end;
    2:begin
      readln(x);
      sterge;
      end;
    3:writeln(h[1].nr);
    end;
  end;
close(output);
close(input);
end.