Description
nodgd的粉丝太多了,每天都会有很多人排队要签名。
今天有𝑛个人排队,每个人的身高都是一个整数,且互不相同。很不巧,nodgd今天去忙别的事情去了,就只好让这些粉丝们明天再来。同时nodgd提出了一个要求,每个人都要记住自己前面与多少个比自己高的人,以便于明天恢复到今天的顺序。
但是,粉丝们或多或少都是有些失望的,失望使她们晕头转向、神魂颠倒,已经分不清楚哪一边是“前面”了,于是她们可能是记住了前面比自己高的人的个数,也可能是记住了后面比自己高的人的个数,而且他们不知道自己记住的是哪一个方向。
nodgd觉得,即使这样明天也能恢复出一个排队顺序,使得任意一个人的两个方向中至少有一个方向上的比他高的人数和他记住的数字相同。可惜𝑛比较大,显然需要写个程序来解决,nodgd很忙,写程序这种事情就交给你了。
Input
第一行输入一个整数𝑛,表示指令的条数。
接下来𝑛行,每行两个整数𝑎𝑖,𝑏𝑖,表示一个人的身高和她记住的数字,保证身高互不相同。
Output
输出一行,这个队列里从前到后的每个人的身高。如果有多个答案满足题意,输出字典序最小。如果不存在满足题意的排列,输出“impossible”(不含引号)。
Solution
这道题首先先要排序,然后就要用二分查答案,就可以了。
Code
#include<bits/stdc++.h>
#define rg register int
using namespace std;
int n,a[100005],b[100005],ans[100005],f[4000005];
int in()
{
rg s=0;
char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch<='9'&&ch>='0') s=s*10+ch-'0',ch=getchar();
return s;
}
void out(rg x)
{
if(x==0) return;
out(x/10),putchar(x%10+'0');
}
void qsort(int l,int r)
{
int i=l,j=r,mid=a[(l+r+1)/2];
while(i<=j)
{
while(a[i]<mid) i++;
while(a[j]>mid) j--;
if(i<=j) swap(a[i],a[j]),swap(b[i],b[j]),i++,j--;
}
if(l<j) qsort(l,j);
if(i<r) qsort(i,r);
}
void change(int y,int x,int l,int r)
{
if(l>y||r<y) return;
if(l==r)
{
f[x]++;
return;
}
int mid=(l+r)/2;
f[x]++;
change(y,x*2,l,mid),change(y,x*2+1,mid+1,r);
}
int find(int sl,int sr,int l,int r,int x)
{
if(sr<l||r<sl||r<l) return 0;
if(sl<=l&&r<=sr) return f[x];
int mid=(l+r)/2;
return find(sl,sr,l,mid,x*2)+find(sl,sr,mid+1,r,x*2+1);
}
int lfind(int x,int l,int r)
{
int now=(l+r)/2;
if(l==r)
{
return l;
}
int fin=find(1,now,1,n,1);
if(now-fin-x>1)
return lfind(x,l,now);
else if(now-fin-x<1)
return lfind(x,now+1,r);
else
return now;
}
int rfind(int x,int l,int r)
{
int now=(l+r)/2;
if(l==r)
{
return l;
}
int fin=find(now,n,1,n,1);
if(n-now-fin-x+1>1)
return rfind(x,now+1,r);
else if(n-now-fin-x+1<1)
return rfind(x,l,now);
else
return now;
}
int main()
{
freopen("queue.in","r",stdin);
freopen("queue.out","w",stdout);
n=in();
for(rg i=1;i<=n;i++) a[i]=in(),b[i]=in();
qsort(1,n);
rg tt,t;
for(rg i=1;i<=n;i++)
{
if(n-i<b[i])
{
printf("impossible");
return 0;
}
t=lfind(b[i],1,n),tt=rfind(b[i],1,n);
while(ans[t]!=0) t--;
while(ans[tt]!=0) tt++;
if(t<1) t=99999;
if(tt>n) tt=99999;
ans[min(t,tt)]=a[i];
change(min(t,tt),1,1,n);
}
for(rg i=1;i<=n;i++) out(ans[i]),putchar(32);
return 0;
}