每个人只记得前边或者后边有多少人比自己高 对于最高的人来说比他高的人不存在 次高的人最多有一个比他高 次次高的人最多有两个比他高。。。以此类推 只要有人超出这个范围就是impossible 而只要每个人都不超出这个范围 那这个队列一定存在(每个人都不超范围<=>队列存在)
因为题目给的条件是比某人高的人在其前或后有多少 且每个人的高度是唯一的 所以我们要按身高从低到高来考虑 这样才能推出每个人的正确位置
假设第i个人说他前或后有k个人比他高 先考虑k个人在前 那么在真正的队列中 这第i个人的前边 除去那些比他矮的人的位置 必须还要有k个位置留给那些比他高的 而先考虑k个人在后也是一样的道理
但是这样结果可能有很多 我们要按题目要求取字典序最小 即上述两种情况得出的位置取最小值即可
#include <bits/stdc++.h>
using namespace std;
struct node1
{
int l;
int r;
int val;
int id;
};
struct node2
{
int h;
int k;
int id;
};
node1 tree[400010];
node2 per[100010];
int n,num;
bool cmp1(node2 n1,node2 n2)
{
return n1.h<n2.h;
}
bool cmp2(node2 n1,node2 n2)
{
return n1.id<n2.id;
}
void pushup(int cur)
{
tree[cur].val=tree[cur*2].val+tree[cur*2+1].val;
return;
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=per[l].h;
tree[cur].r=per[r].h;
tree[cur].val=1;
if(l==r)
{
tree[cur].id=num++;
return;
}
m=(l+r)/2;
build(l,m,cur*2);
build(m+1,r,cur*2+1);
pushup(cur);
return;
}
int queryI(int tar,int cur)
{
if(tree[cur].l==tree[cur].r)
{
return tree[cur].id;
}
if(tar<=tree[cur*2].val) return queryI(tar,cur*2);
else return queryI(tar-tree[cur*2].val,cur*2+1);
}
int queryII(int tar,int cur)
{
if(tree[cur].l==tree[cur].r)
{
return tree[cur].id;
}
if(tar<=tree[cur*2+1].val) return queryII(tar,cur*2+1);
else return queryII(tar-tree[cur*2+1].val,cur*2);
}
void updateI(int tar,int cur)
{
if(tree[cur].l==tree[cur].r)
{
tree[cur].val--;
return;
}
if(tar<=tree[cur*2].val) updateI(tar,cur*2);
else updateI(tar-tree[cur*2].val,cur*2+1);
pushup(cur);
return;
}
void updateII(int tar,int cur)
{
if(tree[cur].l==tree[cur].r)
{
tree[cur].val--;
return;
}
if(tar<=tree[cur*2+1].val) updateII(tar,cur*2+1);
else updateII(tar-tree[cur*2+1].val,cur*2);
pushup(cur);
return;
}
int main()
{
int t,cas,flag,i,l,r,p;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&per[i].h,&per[i].k);
}
printf("Case #%d: ",cas);
sort(per+1,per+n+1,cmp1);
flag=1;
for(i=n;i>=1;i--)
{
if(per[i].k>n-i)
{
printf("impossible\n");
flag=0;
break;
}
}
if(!flag) continue;
num=1;
build(1,n,1);
for(i=1;i<=n;i++)
{
per[i].k++;
l=queryI(per[i].k,1),r=queryII(per[i].k,1);
if(l<r)
{
per[i].id=l;
updateI(per[i].k,1);
}
else
{
per[i].id=r;
updateII(per[i].k,1);
}
}
sort(per+1,per+n+1,cmp2);
for(i=1;i<=n-1;i++)
{
printf("%d ",per[i].h);
}
printf("%d\n",per[i].h);
}
return 0;
}