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;