hdu 2665 区间第k小

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int L[N<<5],R[N<<5],a[N],h[N],T[N],sum[N<<5];
int tot; 
int build(int l,int r){
	int rt=(++tot);sum[rt]=0;
	if(l<r){
		int m=(l+r)>>1;
		L[rt]=build(l,m);
		R[rt]=build(m+1,r);
	}
	return rt;
}
int update(int pre,int l,int r,int x){
	int rt=(++tot);
	L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+1;
	if(l<r){
		int m=(l+r)>>1;
		if(x<=m) L[rt]=update(L[pre],l,m,x);
		else R[rt]=update(R[pre],m+1,r,x);
	}
	return rt;
}
int query(int u,int v,int l,int r,int k)
{
    if(l>=r) return l;
    int m=(l+r)>>1;
    int num=sum[L[v]]-sum[L[u]]; 
    if(num>=k) return query(L[u],L[v],l,m, k);
    else return query(R[u],R[v],m+1,r,k-num);
}
int main(){
	int t,n,m;scanf("%d",&t);
	while(t--){
		tot=0;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]),h[i]=a[i];
		sort(h+1,h+n+1);
		int d=unique(h+1,h+n+1)-h-1;
		T[0]=build(1,d);
		for(int i=1;i<=n;i++){
			int pos=lower_bound(h+1,h+d+1,a[i])-h;
			T[i]=update(T[i-1],1,d,pos);
		}
		while(m--)
    	{
	        int l,r,k;
	        scanf("%d%d%d",&l,&r,&k); 
	        int x=query(T[l-1],T[r],1,d,k);
	        printf("%d\n", h[x]);
    	}
	}
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/vainglory/p/9038147.html