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;