HDU5493 Queue(线段树)

先对高度进行排序

之后模拟插入的方法,因为我们要求比自己高的人在前面或者后面有k个

那么如果当给定的k大于n-i那么说明非法,因为只有n-i个空位剩余,做不到要求。

那么接下来我们考虑是前面有k个还是后面有k个,因为我们是按高度来做的,所以对k和n-i-k取个min,使得前面的空位尽可能少,这就是答案

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
struct seg{
    int x,y;
}s[N];
struct node{
    int l,r;
    int mx;
}tr[N<<2];
int ans[N];
bool cmp(seg a,seg b){
    return a.x<b.x;
}
void pushup(int u){
    tr[u].mx=tr[u<<1].mx+tr[u<<1|1].mx;
}
void build(int u,int l,int r){
    if(l==r){
        tr[u]={l,r,1};
    }
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int x,int d){
    if(tr[u].l==tr[u].r){
        tr[u].mx=0;
        ans[tr[u].l]=d;
        return ;
    }
    int mid=tr[u].l+tr[u].r>>1;
    if(tr[u<<1].mx>x){
        modify(u<<1,x,d);
    }
    else{
        modify(u<<1|1,x-tr[u<<1].mx,d);
    }
    pushup(u);
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int cnt=0;
    while(t--){
        cnt++;
        int n;
        cin>>n;
        int i;
        build(1,1,n);
        for(i=1;i<=n;i++){
            cin>>s[i].x>>s[i].y;
        }
        sort(s+1,s+1+n,cmp);
        int flag=0;
        for(i=1;i<=n;i++){
            if(n-i<s[i].y){
                flag=1;
                break;
            }
            int k=s[i].y;
            k=min(k,n-i-k);
            modify(1,k,s[i].x);
        }
        cout<<"Case #"<<cnt<<": ";
        if(flag){
            cout<<"impossible"<<endl;
            continue;
        }
        for(i=1;i<=n;i++){
            if(i==1)
                cout<<ans[i];
            else
                cout<<" "<<ans[i];
        }
        cout<<endl;
    }
    return 0;
}
View Code

 

posted @ 2021-03-07 09:18  朝暮不思  阅读(53)  评论(0编辑  收藏  举报