Cod sursa(job #306994)

Utilizator mlazariLazari Mihai mlazari Data 22 aprilie 2009 17:46:26
Problema Range minimum query Scor 40
Compilator fpc Status done
Runda Arhiva educationala Marime 1.45 kb
Program Rmq;
var Intrare,Iesire : text;
    a,log2 : array[1..100000] of longint;
    mk : array[1..100000,0..16] of longint;
    d : array[0..16] of longint;
    n,m : longint;

procedure DeschideFisiere;
begin
  assign(Intrare,'rmq.in');
  reset(Intrare);
  assign(Iesire,'rmq.out');
  rewrite(Iesire);
end;

function min(x,y : longint) : longint;
begin
  if x<y then min:=x else min:=y;
end;

procedure preprocesare;
var i,k : longint;
begin
  d[0]:=1;
  for i:=1 to 16 do d[i]:=2*d[i-1];
  for i:=1 to n do log2[i]:=0;
  for i:=0 to 16 do log2[d[i]]:=i;
  k:=0;
  for i:=1 to n do
   if log2[i]=0 then log2[i]:=k else k:=log2[i];
  for i:=1 to n do mk[i,0]:=a[i];
  for k:=1 to log2[n] do begin
    for i:=1 to n do
     if n-i+1>d[k-1] then mk[i,k]:=min(mk[i,k-1],mk[i+d[k-1],k-1])
     else mk[i,k]:=mk[i,k-1];
  end;
end;

function minim(x,y : longint) : longint;
var l,mn : longint;
begin
  l:=log2[y-x+1];
  mn:=mk[x,l];
  x:=x+d[l];
  while x<=y do begin
    l:=log2[y-x+1];
    mn:=min(mn,mk[x,l]);
    x:=x+d[l];
  end;
  minim:=mn;
end;

procedure proceseaza;
var i,x,y : longint;
begin
  readln(Intrare,n,m);
  for i:=1 to n do readln(Intrare,a[i]);
  preprocesare;
  for i:=1 to m do begin
    readln(Intrare,x,y);
    writeln(Iesire,minim(x,y));
  end;
end;

procedure InchideFisiere;
begin
  close(Intrare);
  close(Iesire);
end;

begin
  DeschideFisiere;
  proceseaza;
  InchideFisiere;
end.