• hdu5493 树状数组+二分


    数字的字典序,,有点迷,网上看题解也没有明说,总之越大的数字放在后面就行了

    利用二分找到前k个空位即可

    /*
    每个人有一个独特的高度,第i个人高hi,前面有ki个人比他高或后面有ki个人比他高 
    请求出可能队列,
    
    升序排列身高,每个人可选的位置是第k+1个空位或者第n-i-k个空位, 
    如果n-i-k<=0,那么就是impossible
    结果要按照字典序输出,所以如果有两个可选位置可以插入时,需要判断从前往后插还是从后往前插好。
    插入时按照二分找到树状数组中第k+1个空位 
    离线离散化,树状数组维护空位
    复杂度O(nlognlogn) 
    */
    #include<bits/stdc++.h>
    #define maxn 100005
    
    using namespace std;
    
    struct node{int h,k;}p[maxn];
    int cmp(node a,node b){return a.h<b.h;}
    int bit[maxn],ans[maxn],n; 
    void add(int x,int num){
        for(int i=x;i<=n;i+=i&-i)
            bit[i]+=num;
    }
    int query(int x){
        int res=0;
        for(int i=x;i;i-=i&-i)
            res+=bit[i];
        return res;
    }
    
    int main(){
        int t,flag;
        scanf("%d",&t);
        for(int tt=1;tt<=t;tt++){
            scanf("%d",&n);
            memset(bit,0,sizeof bit);
            flag=0;
            for(int i=1;i<=n;i++) add(i,1);
            for(int i=1;i<=n;i++)scanf("%d%d",&p[i].h,&p[i].k);
            sort(p+1,p+1+n,cmp); 
            for(int i=1;i<=n;i++){
                int pos1=p[i].k+1,pos2=n-i-p[i].k+1;
                if(pos2<=0){
                     flag=1;
                     break;
                }
                int pos=min(pos1,pos2);//为了字典序最小找一个最小的位置 
                int l=1,r=n,mid,anss;
                while(l<=r){
                    mid=l+r>>1;
                    if(query(mid)<pos)
                        l=mid+1;
                    else anss=mid,r=mid-1;
                }
                add(anss,-1);
                ans[anss]=p[i].h;
            }
            if(flag)printf("Case #%d: impossible
    ",tt);
            else {
                printf("Case #%d:",tt);
                for(int i=1;i<=n;i++) printf(" %d",ans[i]);
                puts("");
            }
        } 
        return 0; 
    } 
  • 相关阅读:
    K好数
    最大最小公倍数
    十六进制转十进制
    利用malloc定义数组
    01字串
    ubuntu 14.04 下jdk和sdk+eclipse 的配置
    Mysql3
    求最大连续子串
    UC笔试
    java实现随机洗牌算法
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10147363.html
Copyright © 2020-2023  润新知