划分树

本文介绍了一种使用离线算法解决静态数组中区间第K小值问题的方法。通过快速排序预处理数组,并构建特殊的数据结构辅助查询,实现对任意区间内第K小元素的有效检索。

邪恶的东西……思想简单,实现巨复杂……搞了好久才看懂标程

问题:考虑一个静态问题,给出一个数组,每次询问任意区间【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.

转载于:https://www.cnblogs.com/Lr-bob/archive/2012/02/22/2364001.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值