[gotoac]划分树 beta1

来源:互联网 发布:php设置redis过期时间 编辑:程序博客网 时间:2024/06/08 06:19
struct DivideTree{#define lson l,mid,floor+1#define rson mid+1,r,floor+1int 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;

原创粉丝点击