划分树-区间第k值
小红的中位数查询(easy)
#include<bits/stdc++.h>
using namespace std;
const int N=200005,M=20;
int n,m;
#define mid ((le+ri)>>1)
#define lson le,mid,dep+1
#define rson mid+1,ri,dep+1
struct Node{
int num[N],toleft[N];
};
Node t[M];
int sorted[N];
void build(int le,int ri,int dep){
if(le==ri){
return;
}
int key=sorted[mid];
int equ=mid-le+1;
for(int i=le;i<=ri;i++){
if(t[dep].num[i]<key){
equ--;
}
}
int tl=0;
int it1=le-1,it2=mid;
for(int i=le;i<=ri;i++){
int now=t[dep].num[i];
if(now<key||(now==key&&equ)){
if(now==key){
equ--;
}
tl++;
t[dep+1].num[++it1]=now;
}
else{
t[dep+1].num[++it2]=now;
}
t[dep].toleft[i]=tl;
}
build(lson);
build(rson);
}
int query(int le,int ri,int dep,int x,int y,int z){
if(le==ri){
return t[dep].num[le];
}
int tl=0,del=t[dep].toleft[y];
if(le!=x){
tl=t[dep].toleft[x-1];
del-=tl;
}
int nx,ny;
if(del>=z){
nx=le+tl;
ny=nx+del-1;
return query(lson,nx,ny,z);
}
else{
nx=mid+1+x-tl-le;
ny=nx+y-x-del;
return query(rson,nx,ny,z-del);
}
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
t[0].num[i]=x;
sorted[i]=t[0].num[i];
}
sort(sorted+1,sorted+1+n);
build(1,n,0);
for(int i=1;i<=m;i++){
int x,y,z;
scanf("%d %d",&x,&y);
z = (y - x )/2 + 1;
int ans=query(1,n,0,x,y,z);
printf("%d\n",ans);
}
return 0;
}