设为首页 加入收藏

TOP

划分树详解 结合例题hdu4251(二)
2012-11-17 09:28:12 来源: 作者: 【 】 浏览:970
Tags:划分 详解   结合 例题 hdu4251


 
//如果suppose==1,则说明数组中值为sorted[mid]只有一个数。比如序列:1 3 4 5 6,sorted[mid]=4  
 
/*如果suppose>1,则说明数组中左半边值为sorted[mid]的不止一个数,为mid-suppose。比如序列:1 4 4 4 6,sorted[mid]=4 
 
*/  
 
int lpos=left,rpos=mid+1;  
 
for(i=left;i<=right;i++){  
 
if(i==left){//这里是预处理,相当与初始化  
 
toLeft[level][i]=0;  
 
}else{  
 
toLeft[level][i]=toLeft[level][i-1];  
 
}  
 
if(tree[level][i]<sorted[mid]){//划分到中位数左边  
 
toLeft[level][i]++;  
 
tree[level+1][lpos++]=tree[level][i];  
 
}else if(tree[level][i]>sorted[mid]){//划分到中位数右边  
 
tree[level+1][rpos++]=tree[level][i];  
 
}else{//这里,suppose大于0的数划分到中位数的左边  
 
if(suppose!=0){//这里的处理太巧妙了!帅气!  
 
suppose--;  
 
toLeft[level][i]++;  
 
tree[level+1][lpos++]=tree[level][i];  
 
}else{//表示  
 
tree[level+1][rpos++]=tree[level][i];  
 
}  
 
}  
 
}  
 
build(level+1,left,mid);  
 
build(level+1,mid+1,right);  
 
}  
 
//在[left,right]数据中查询[qleft,qright]中第k大的数据  
 
int query(int level,int left,int right,int qleft,int qright,int k){  
 
if( qleft==qright)  
 
return tree[level][qleft];  
 
int s;//代表[left,qleft)之间有多个个元素被分到左边  
 
int ss;//[qleft, qright]内将被划分到左子树的元素数目  
 
int mid=(left+right)>>1;  
 
if(left==qleft){  
 
s=0;  
 
ss=toLeft[level][qright];  
 
}else{  
 
s=toLeft[level][qleft-1];  
 
ss=toLeft[level][qright]-s;  
 
}  
 
int newl,newr;  
 
if(k<=ss){//查询左边  
 
newl=left+s;  
 
newr=left+s+ss-1;  
 
return query(level+1,left,mid,newl,newr,k);  
 
}else{//查询右边  
 
newl=mid-left+1+qleft-s;  
 
newr=mid-left+1+qright-s-ss;  
 
return query(level+1,mid+1,right,newl, newr,k - ss);  
 
}  
 
}  
 
int main(){  
 
int n,m;  
 
while(scanf("%d %d",&n,&m)!=EOF) 
 
{  
 
        int i;  
 
        for(i=1;i<=n;i++){  
 
            scanf("%d",&tree[0][i]);  
 
            sorted[i]=tree[0][i];  
 
        }  
 
        sort(sorted+1,sorted+n+1);  
 
        build(0,1,n);  
 
        for(i=0;i<n;i++){  
 
            for(int j=1;j<=n;j++){  
 
                printf("%d ",toLeft[i][j]);  
 
            }  
 
            printf("\n");  
 
        }  
 
        int ql,qr,k;  
 
        for(i=0;i<m;i++){  
 
            scanf("%d %d %d",&ql,&qr,&k);  
 
            printf("%d\n",query(0,1,n,ql,qr,k));  
 
        }  
 
}  
 
return 0;  
 
}

        

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++二维数组的动态分配 下一篇用栈实现的自动走迷宫

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: