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

HDU 5493 Queue(2015 ACM/ICPC Asia Regional Hefei Online)

2016-07-14 09:54 417 查看

题目分析

一道线段树的题目,因为是前面或者后面有k个比自己高的人,所以我们应该按照由身高从小到大排序,这样前面的人对后面的人就没有什么影响。我们线段树中存的是每一段有多少空位置。这样每次如果根节点的空位置小于k,那么很明显没办法放,同样因为前面对后面的没有什么影响,我只需要找到k和n-k-i中较小的,如果这个值小于0,那么则没有办法继续插入。因为满足字典序最小,因此往最前面位置插入就可以了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define mid (L+R)/2
#define lson o<<1, L, mid
#define rson o<<1|1, mid+1, R
const int maxn = 100005;

struct Node{
int h,k;
bool operator < (const Node a)const{
return h < a.h;
}
}node[maxn];

int sum[maxn<<2],loc[maxn];

void build(int o,int L,int R){
sum[o] = (R-L+1);
if(L == R) return ;
build(lson);
build(rson);
}

void update(int o,int L,int R,int p,int val){
if(L == R){
sum[o] = 0;
loc[L] = val;
return ;
}
if(sum[o<<1] >= p) update(lson, p, val);
else update(rson, p-sum[o<<1], val);
sum[o] = sum[o<<1] + sum[o<<1|1];
}

int main(){
int T,N;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++){
scanf("%d", &N);
for(int i = 1; i <= N; i++) scanf("%d%d", &node[i].h, &node[i].k);
sort(node+1, node+N+1);
int flag = 0;
build(1,1,N);
for(int i = 1; i <= N; i++){
int temp = min(node[i].k, N-i-node[i].k);
if(temp < 0) {flag = 1; break;}
if(node[i].k < N-i-node[i].k)
update(1, 1, N, node[i].k+1, node[i].h);
else
update(1, 1, N, N-i-node[i].k+1, node[i].h);
}
printf("Case #%d: ", kase);
if(flag) printf("impossible\n");
else for(int i = 1; i <= N; i++){
if(i != N) printf("%d ", loc[i]);
else printf("%d\n", loc[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: