Cod sursa(job #297615)

Utilizator katamashCatalin Tamas katamash Data 5 aprilie 2009 15:03:23
Problema Hotel Scor 100
Compilator fpc Status done
Runda preONI Marime 7.14 kb
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.