【二分+树状数组】HDU 5493 Queue

题意

参考思路

代码

主要是记录一下自己的写的代码,中间debug好久,在一些小地方犯错

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<vector>
#include<map>
#include<algorithm>
#include<set>
#include<string>
#include<queue>
#include<stack>

using namespace std;
#define ll long long
#define fi first
#define se second
#define sc(n) scanf("%d",&n)
#define exp 1e-9
typedef pair<ll, ll> lp;
typedef pair<int,int> ii;
typedef vector<vector<ll> > vvl;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const double PI = acos(-1);
int lowbit(int x){
    return x&(-x);
}
void update(vector<int>& data,int x,int delta){
    while(x<data.size()){
        data[x]+=delta;
        x+=lowbit(x);
    }
}
int query(vector<int>& data,int x){
    int ans=0;
    while(x){
        ans+=data[x];
        x-=lowbit(x);
    }
    return ans;
}

void J(){
    int t;
    sc(t);
    for(int kase=1;kase<=t;kase++){
        //cout<<"debug1"<<endl;
        int n;
        sc(n);
        vector<ii> a;
        vector<int> data(n+1,0);//1 表示空位的数量
        vector<int> res(n+1,0);
        //data[0]=0;
        //build(data);
        for(int i=1;i<=n;i++){
            int x,y;
            scanf("%d %d",&x,&y);
            a.emplace_back(x,y);
            update(data,i,1);
        }
        sort(a.begin(),a.end());
        bool error=false;
        for(int i=1;i<=n;i++){
            //按身高从小到大安放每个人的位置
            //二分每个人的最佳位置
            if(a[i-1].second>n-i) {
                error=true;
                break;
            }
            int l=1,r=n;
            int p=min(a[i-1].second,n-i-a[i-1].second)+1;
            while(l<r){
                //cout<<l<<" "<<r<<endl;
                int mid=l+(r-l)/2;
                //二分每个位置,找到那个pos,使得前pos位恰好有p个空位
                int cnt=query(data,mid);
                if(cnt<p) l=mid+1;
                else r=mid;
            }
            update(data,l,-1);//更新空位,在该位置
            res[l]=a[i-1].first;
        }
        if(error){
            printf("Case #%d: impossible\n",kase);
        }
        else{
            printf("Case #%d:",kase);
            for(int i=1;i<=n;i++) printf(" %d",res[i]);
            printf("\n");
        }
    }
}
int main() {
//    freopen("C:\\data\\code\\cppCode\\kuangbin_bi_slide_monoQueue\\in.txt", "r", stdin);
//    freopen("C:\\data\\code\\cppCode\\kuangbin_bi_slide_monoQueue\\out.txt", "w", stdout);
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
    J();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值