划分树
邪恶的东西……思想简单,实现巨复杂……搞了好久才看懂标程
问题:考虑一个静态问题,给出一个数组,每次询问任意区间【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.