您的位置:首页 > 产品设计 > UI/UE

HDU - 5493 Queue 2015 ACM/ICPC Asia Regional Hefei Online(线段树)

2015-09-27 20:45 495 查看
按身高排序,每个人前面最高的人数有上限,如果超出上限说明impossible,

每次考虑最小的人,把他放在在当前的从左往右第k+1个空位

因为要求字典序最小,所以每次k和(上限-k)取min值。

没有修改操作,只有删除,可用线段树维护空位数量s,每次类似名次树判断一下第k个空位在哪颗子树上(原来这叫划分树

到达叶子返回位置编号并减少空位数量,push_up的时候维护一下空位数量。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;
struct Nd
{
int h,k;
void IN(){ scanf("%d%d",&h,&k); }
bool operator < (const Nd& rh) const{
return h < rh.h;
}
}nd[maxn];
int N;

bool chk()
{
sort(nd,nd+N);
for(int i = 0,n = N-1; i <= n; i++){
if(nd[i].k > n-i) return false;
nd[i].k = min(nd[i].k,n-i-nd[i].k);
}
return true;
}

#define lo (o<<1)
#define ro (o<<1|1)
#define lsn L, M, lo
#define rsn M+1,R, ro
#define mid int M = (L+R)>>1;
#define para int L = 0, int R = N-1,int o = 1

int s[maxn<<2];
void build(para)
{
s[o] = R-L+1;
if(L==R) return;
mid
build(lsn);
build(rsn);
}

int qk;
int qud(para)
{
if(L==R){ s[o]--; return L; }
mid
int re = 0;
if(s[lo]>=qk) re = qud(lsn);
else { qk -= s[lo];re = qud(rsn); }
s[o] = s[lo] + s[ro];
return re;
}

int ans[maxn];

//#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
int T, ks = 0; scanf("%d",&T);
while(T--){
scanf("%d",&N);
for(int i = 0; i < N; i++) nd[i].IN();
printf("Case #%d:",++ks);
if(!chk()) { puts(" impossible"); continue; }
build();
for(int i = 0; i < N; i++){
qk = nd[i].k+1;
ans[qud()] = nd[i].h;
}
for(int i = 0; i < N; i++){
printf(" %d",ans[i]);
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: