[gotoac]划分树 beta1

struct DivideTree{
	#define lson l,mid,floor+1
	#define rson mid+1,r,floor+1
	int tol[22][M];            //tol[i][j]:第i层第j个前有多少个数分配到左子
	int val[22][M],sorted[M];  //val[0]是原始数组,sorted是升序排序后的数组
	void read(int n){    //n为数组长度
		for(int i=1;i<=n;i++)
			scanf("%d",&val[0][i]),sorted[i]=val[0][i];
		sort(sorted+1,sorted+n+1);
	}
	void setPos(int floor,int curPos,int& newPos){
		val[floor+1][newPos++]=val[floor][curPos];
	}
	void build(int l,int r,int floor){
		if(l==r) return;
		int i,mid=middle,lsame=mid-l+1;
		for(i=l;i<=r;i++) if(val[floor][i]<sorted[mid]) lsame--;
		int lpos=l,rpos=mid+1,same=0;
		for(i=l;i<=r;i++){
			tol[floor][i]= (i==l)? 0:tol[floor][i-1];
			if(val[floor][i]<sorted[mid])
				tol[floor][i]++,setPos(floor,i,lpos);
			else if(val[floor][i]>sorted[mid])
				setPos(floor,i,rpos);
			else{
				if(same>=lsame) setPos(floor,i,rpos);
				else same++,tol[floor][i]++,setPos(floor,i,lpos);
			}
		}
		build(lson),build(rson);
	}
	int query(int l,int r,int floor,int L,int R,int k){
		if(L==R) return val[floor][L];
		int x,xx;//[L,R]有几个分到左边,[l,L-1]有几个分到左边
		if(L==l) x=tol[floor][R],xx=0;
		else x=tol[floor][R]-(xx=tol[floor][L-1]);
		int mid=middle;
		if(x>=k){
			int newL=l+xx,newR=newL+x-1;
			return query(lson,newL,newR,k);
		}else{
			int y=R-L+1-x;//[L,R]有几个分到右边
			int yy=L-l-xx;//[l,L-1]有几个分到左边
			int newL=mid+1+yy,newR=newL+y-1;
			return query(rson,newL,newR,k-x);
		}
	}
}p;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值