邪恶的东西……思想简单,实现巨复杂……搞了好久才看懂标程
问题:考虑一个静态问题,给出一个数组,每次询问任意区间【l,r】内的第k小值,设计一个离线算法
Code:
Program HFS;
var
a,sort : array[1..10000] of longint;
s,z : array[1..10,1..100000] of longint;
n,m,x,y,k : longint;
i : longint;
Procedure Qsort(l,r:longint);
var
i,j,t,m : longint;
begin
i:=l ; j:=r; m:=a[(l+r) shr 1];
repeat
while a[i]<m do inc(i);
while a[j]>m do dec(j);
if i<=j then
begin
t:=a[i]; a[i]:=a[j]; a[j]:=t;
t:=sort[i]; sort[i]:=sort[j]; sort[j]:=t;
inc(i); dec(j);
end;
until i>j;
if i<r then Qsort(i,r);
if l<j then Qsort(l,j);
end;
Procedure Build(h,l,r:longint);
var
i,mid,p : longint;
begin
mid:=(l+r) shr 1+1; p:=0;
for i:=l to r do
if z[h,i]<mid then
begin
z[h+1,l+p]:=z[h,i];
inc(p);
s[h,i]:=p;
end else
begin
z[h+1,mid+i-p-l]:=z[h,i];
s[h,i]:=p;
end;
if p>1 then Build(h+1,l,mid-1);
if mid<r then Build(h+1,mid,r);
end;
Function find(h,st,et,l,r,k:longint):longint;
var
beg,ed,mid : longint;
begin
if st=et then exit(z[h,st]);
mid:=(st+et) shr 1+1;
if st=l then beg:=0 else beg:=s[h,l-1];
ed:=s[h,r];
if ed-beg>=k then
exit(find(h+1,st,mid-1,st+beg,st+ed-1,k)) else
exit(find(h+1,mid,et,mid+l-st-beg,mid+r-st-ed,k-(ed-beg)));
end;
begin
assign(input,'HFS.in');
assign(output,'HFS.out');
reset(input); rewrite(output);
readln(n,m);
for i:=1 to n do
begin
read(a[i]);
sort[i]:=i;
end;
readln;
Qsort(1,n);
for i:=1 to n do z[1,sort[i]]:=i;
Build(1,1,n);
for i:=1 to m do
begin
readln(x,y,k);
writeln(a[sort[find(1,1,n,x,y,k)]]);
end;
close(input); close(output);
end.