Cod sursa(job #449338)

Utilizator cristi12345Balu Cristian cristi12345 Data 6 mai 2010 11:04:12
Problema Hotel Scor 100
Compilator fpc Status done
Runda Arhiva de probleme Marime 6.26 kb
Program HOTEL;

const filein='hotel.in';
      fileout='hotel.out';
      MAXN=100000;
      MAXB=100000;
      MAXS=210000;

type intarray=array[0..MAXN+1] of longint;
     dintarray=array[0..MAXS] of longint;
     longarray=array[0..MAXN+1] of longint;
     pint=^intarray;
     p2int=^dintarray;
     plong=^longarray;
     buffer=array[1..MAXB] of char;
     pbuf=^buffer;

var fin,fout:text;
    lungdr,heapld,pozhp:pint;
    fiu:array[1..2] of p2int;
    tata,li,ls,numdr:p2int;
    i,j,k,m,n,p,c,a,b,pd,last,size:longint;
    bufi,bufo:pbuf;

procedure initFiles;
begin
new(bufi);
fillchar(bufi^,sizeof(buffer),0);
new(bufo);
fillchar(bufo^,sizeof(buffer),0);

assign(fin,filein);
settextbuf(fin,bufi^,sizeof(buffer));
reset(fin);

assign(fout,fileout);
settextbuf(fout,bufo^,sizeof(buffer));
rewrite(fout);
end;

procedure initArrays;
begin
new(lungdr);
fillchar(lungdr^,sizeof(intarray),0);
lungdr^[1]:=n;

new(heapld);
fillchar(heapld^,sizeof(intarray),0);
new(pozhp);
fillchar(pozhp^,sizeof(intarray),0);

for i:=1 to n do
  begin
    heapld^[i]:=i;
    pozhp^[i]:=i;
  end;

new(tata);
fillchar(tata^,sizeof(dintarray),0);
new(li);
fillchar(li^,sizeof(dintarray),0);
new(ls);
fillchar(ls^,sizeof(dintarray),0);
new(numdr);
fillchar(numdr^,sizeof(dintarray),0);

for i:=1 to 2 do
  begin
    new(fiu[i]);
    fillchar(fiu[i]^,sizeof(dintarray),0);
  end;
end;

procedure closeFiles;
begin
close(fin);
close(fout);
end;

procedure MakeIntervals;
begin
last:=0;
for i:=1 to n do
  begin
    fiu[1]^[i]:=0; fiu[2]^[i]:=0;
    li^[i]:=i; ls^[i]:=i;
  end;
k:=n;

while (k>1) do
  begin
    j:=last+k; k:=0;
    for i:=last+1 to j do
      if ((i-last) and 1=1) then
        begin
          if (i+1<=j) then
            begin
              inc(k);
              tata^[i]:=j+k;
              tata^[i+1]:=j+k;
              li^[j+k]:=li^[i];
              ls^[j+k]:=ls^[i+1];
              fiu[1]^[j+k]:=i;
              fiu[2]^[j+k]:=i+1;
            end
          else
            begin
              inc(k);
              tata^[i]:=j+k;
              li^[j+k]:=li^[i];
              ls^[j+k]:=ls^[i];
              fiu[1]^[j+k]:=i;
              fiu[2]^[j+k]:=0;
            end;
        end;
    last:=j;
  end;

size:=last+k;
tata^[size]:=size+1;
end;

procedure up(poz:longint);
var php,ptata,vaux:longint;
begin
php:=pozhp^[poz];
ptata:=php shr 1;

while (ptata>0) and (lungdr^[heapld^[ptata]]<lungdr^[heapld^[php]]) do
  begin
    vaux:=heapld^[ptata];
    heapld^[ptata]:=heapld^[php];
    heapld^[php]:=vaux;

    pozhp^[heapld^[ptata]]:=ptata;
    pozhp^[heapld^[php]]:=php;

    php:=ptata;
    ptata:=php shr 1;
  end;
end;

procedure down(poz:longint);
var p1,p2,v1,v2,v,php:longint;
    sw:boolean;
begin
php:=pozhp^[poz];

repeat
sw:=false;

p1:=php shl 1;
p2:=p1+1;

if (p1<=n) then
  v1:=lungdr^[heapld^[p1]]
else
  v1:=-1;

if (p2<=n) then
  v2:=lungdr^[heapld^[p2]]
else
  v2:=-1;

v:=lungdr^[heapld^[php]];

if (v1>=v2) and (v1>v) then
  begin
    sw:=true;
    v:=heapld^[p1];
    heapld^[p1]:=heapld^[php];
    heapld^[php]:=v;

    pozhp^[heapld^[p1]]:=p1;
    pozhp^[heapld^[php]]:=php;

    php:=p1;
  end
else
if (v2>=v1) and (v2>v) then
  begin
    sw:=true;
    v:=heapld^[p2];
    heapld^[p2]:=heapld^[php];
    heapld^[php]:=v;

    pozhp^[heapld^[p2]]:=p2;
    pozhp^[heapld^[php]]:=php;

    php:=p2;
  end;
until (not sw);
end;

procedure searchok(nint:longint;var ppp:longint);
var f1,f2:longint;
begin
ppp:=0;
while (nint>n) do
  begin
    f1:=fiu[1]^[nint];
    f2:=fiu[2]^[nint];

    if (numdr^[f2]>0) then
      nint:=f2
    else
      nint:=f1;
  end;

ppp:=nint;
end;

procedure searchdr(lpoz:longint;var pp:longint);
var num,ii,l1:longint;
    ok:boolean;
begin
pp:=0;

ok:=false;
num:=lpoz;
while (ls^[num]=lpoz) and (num<=size) and (numdr^[num]=0) do
  num:=tata^[num];

if (num<=size) and (ls^[num]=lpoz) and (numdr^[num]>0) then
  searchok(num,pp)
else
if (num<size) and (ls^[num]>lpoz) then
  begin
    l1:=li^[num]-1;

    if (l1>0) then
      searchdr(l1,pp);
  end;
end;

procedure increase(poz:longint);
var ind:longint;
begin
ind:=poz;
while (ind<=size) do
  begin
    inc(numdr^[ind]);
    ind:=tata^[ind];
  end;
end;

procedure decrease(poz:longint);
var ind:longint;
begin
ind:=poz;
while (ind<=size) do
  begin
    dec(numdr^[ind]);
    ind:=tata^[ind];
  end;
end;

begin
initFiles;
readln(fin,n,p);
initArrays;
MakeIntervals;
increase(1);

while (p>0) do
  begin
    read(fin,c);
    if (c<3) then
      begin
        read(fin,a,m);
        b:=a+m-1;
      end;

    case c of
    1:begin
        searchdr(a,i);
        j:=i+lungdr^[i]-1;

        if (a=i) then
          begin
            lungdr^[i]:=0;
            decrease(i);
            down(i);
          end
        else
          begin
            lungdr^[i]:=a-i;
            down(i);
          end;

        if (b<j) then
          begin
           lungdr^[b+1]:=j-b;
           increase(b+1);
           up(b+1);
          end;
      end;
    2:begin
        searchdr(a,i);
        j:=i+lungdr^[i]-1;

        if (j=a-1) then
          begin
            if (lungdr^[b+1]>0) then
              begin
                pd:=b+lungdr^[b+1];

                lungdr^[i]:=pd-i+1;
                up(i);

                lungdr^[b+1]:=0;
                decrease(b+1);
                down(b+1);
              end
            else
              begin
                lungdr^[i]:=b-i+1;
                up(i);
              end;
          end
        else
          begin
            if (lungdr^[b+1]>0) then
              begin
                pd:=b+lungdr^[b+1];
                lungdr^[a]:=pd-a+1;
                increase(a);
                up(a);

                lungdr^[b+1]:=0;
                decrease(b+1);
                down(b+1);
              end
            else
              begin
                lungdr^[a]:=b-a+1;
                increase(a);
                up(a);
              end;
          end;
      end;
    3:begin
        writeln(fout,lungdr^[heapld^[1]]);
      end;
    end;

    dec(p);
  end;

closeFiles;

end.