hdu5493 树状数组+二分

来源:互联网 发布:社交软件的普遍性 编辑:程序博客网 时间:2024/06/05 06:24

题意有一群人排队,每个的身高都是独一无二的,每个的只知道前面k个人比他高,或者后面k个人比他高,求身高字典序最小的一种排法

即将身高从矮到高排序,每次尽可能地使得当前这个人靠前就好了,每次放的时候能够知道前面要留多少个空位给后面比他高的人,比如p个,这里就是利用树状数组维护一个前缀和,并用二分去查找第p+1个空位放这人

#include<iostream>#include<stdio.h>#include<string.h>#include<string>#include<stdlib.h>#include<cmath>#include<queue>#include<algorithm>using namespace std;#define rd(x) scanf("%d",&x)#define rdd(x,y) scanf("%d%d",&x,&y)#define rddd(x,y,z) scanf("%d%d%d",&x,&y,&z)#define rdddd(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)#define rds(s) scanf("%s",s)#define rep(i,n) for(int i=0;i<n;i++)#define LL long longconst int N = 2e5+10;const int M=2000;const int inf=0x3f3f3f3f;const double eps=1e-8;int MOD=1e9+7;int cas=1;int n,m,q;#define lowbit(x) x&(-x)struct node{    int h,k;    bool operator <(const node& o) const{        return h<o.h;    }}a[N];int sum[N];void add(int x){        for(int i=x;i<=n;i+=lowbit(i))          sum[i]++;}int query(int x){    int ret=0;    for(int i=x;i>0;i-=lowbit(i)) ret+=sum[i];    return ret;}int calc(int p){    if(p<0) return -1;    int l=1,r=n;    int ans=-1;    while(l<=r){        int m=l+r>>1;        int num=query(m);        int left=m-num;        if(left<p) l=m+1;        else if(left>p) r=m-1;        else {            int has=query(m)-query(m-1);            if(has==1) r=m-1;            else return m;        }    }    return -1;}int ans[N];int main(){#ifndef ONLINE_JUDGE  freopen("aaa","r",stdin);#endif    int T;    rd(T);    while(T--){          rd(n);            for(int i=1;i<=n;i++){                rdd(a[i].h,a[i].k);            }            sort(a+1,a+n+1);            for(int i=0;i<=n;i++) sum[i]=0;            bool ok=true;            for(int i=1;i<=n && ok;i++){                int h=a[i].h,k=a[i].k;                int left=n-i;                int p;                if(k>left){                    ok=false;break;                }                if(k<=left/2) p=k;                else p=left-k;                int ret=calc(p+1);                if(ret==-1) ok=false;                else{                    add(ret);                    ans[ret]=h;                }            }            printf("Case #%d: ",cas++);            if(!ok) puts("impossible");            else{                for(int i=1;i<=n;i++){                    printf("%d%c",ans[i],i<n?' ':'\n');                }            }            //for(int i=1;i<=n;i++) printf("%d%s",pos[i],);    }    return 0;}



0 0