Cod sursa(job #391957)

Utilizator mimarcelMoldovan Marcel mimarcel Data 6 februarie 2010 16:15:54
Problema Heapuri Scor 10
Compilator fpc Status done
Runda Arhiva educationala Marime 2.2 kb
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: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
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:=m;
  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 interschimba(var a,b:longint);
begin
a:=a xor b;
b:=b xor a;
a:=a xor b;
end;

procedure jos(a:longint);
var f:longint;
begin
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<h[a].nr then begin
                        v[h[f].poz]:=a;
                        v[h[a].poz]:=f;
                        interschimba(h[f].nr,h[a].nr);
                        a:=f;
                        end
                   else break;
until false;
end;

procedure sterge;
begin//sterg al x-lea numar inserat => sterg h[v[x]]
x:=v[x];
h[x]:=h[m];
dec(m);
if(x<>1)and(x<>m+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;
for i:=1 to n do
  begin
  read(cod);
  case cod of
    1:begin
      readln(x);
      insert;
      end;
    2:begin
      readln(x);
      sterge;
      end;
    3:writeln(h[1].nr);
    end;
  end;
close(output);
close(input);
end.