PDA

View Full Version : Range Minimum Query [RMQ]



songohan2009
29-01-2010, 22:55
Các bạn cho mình hỏi Code RMQ sau của mình sai chỗ nào vậy? :-??
Đề bài là nhập dãy A. Có Q truy vấn, mỗi truy vấn trả ra phần tử min trong đoạn u->v.
Mình mới học RMQ, mong các bạn giúp đỡ. :D



var
n : longint;
a : array[0..100] of longint;
f : array[0..1000 , 0..1000] of longint;

procedure inp;
var
i : longint;
begin
readln(n);
for i := 1 to n do
read(a[i]);
readln;
end;

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

procedure process;
var
i , j , k : longint;
begin
for i := 1 to n do
f[i,0] := a[i];
k := trunc(ln(n)/ln(2));

for j := 1 to k do
for i := 1 to n - 1 shl j + 1 do
f[i,j] := min(f[i,j-1] , f[i+1 shl j,j-1]);
end;

function findmin(i , j : longint) : longint;
var
k : longint;
begin
k := trunc(ln(j-i+1)/ln(2));
exit( min(f[i,k] , f[j-1 shl k+1 , k]) );
end;

procedure query;
var
i , q , u , v : longint;
begin
readln(q);
for i := 1 to q do
begin
readln(u , v);
writeln(FindMin(u , v));
end;
end;

begin
inp;
process;
query;
end.

mr_invincible
09-02-2010, 02:11
Bạn nên tự sinh một số test vừa phải (chẳng hạn có khoảng 20 phần tử, 100 truy vấn), viết 1 chương trình duyệt rồi kiểm tra. Như vậy sẽ có tác dụng tốt hơn : D. Mình test thử 1 test tay sau cũng thấy sai:
6
2 4 3 1 5 6
1
1 3
=> mình đoán là đoạn findmin tính sai chỉ số.

Bài của bạn còn sai chỗ procedure process: k := trunc(ln(n)/ln(2)); => mảng RMQ ngắn hơn cần thiết.