B组
T1.
模拟一下就能发现,从小到大排序后,就是在一个长度为n的序列上插入到第k个空位,因为要字典序小,尽量往左插入,所以k=min(y+1,n-i-y+1)
这个可以用线段树二分维护一下!
#include<algorithm> #include<iostream> #include<cstdio> using namespace std; inline int rd(){ int ret=0,f=1;char c; while(c=getchar(),!isdigit(c))f=c=='-'?-1:1; while(isdigit(c))ret=ret*10+c-'0',c=getchar(); return ret*f; } const int MAXN=100005; struct Node{ int x,y; bool operator<(const Node &rhs)const { return x<rhs.x; } }a[MAXN]; int n; int lef[MAXN]; #define ls (cur<<1) #define rs (cur<<1|1) #define mid (l+r>>1) int val[MAXN<<2],elm[MAXN<<2]; void pushup(int cur){ val[cur]=val[ls]+val[rs]; } void build(int cur,int l,int r){ if(l==r){val[cur]=1;lef[l]=cur;return;} build(ls,l,mid);build(rs,mid+1,r); pushup(cur); } void update(int cur,int l,int r,int w,int id){ if(l==r){val[cur]=0;elm[cur]=id;return;} if(val[ls]>=w) update(ls,l,mid,w,id); else update(rs,mid+1,r,w-val[ls],id); pushup(cur); } int main(){ freopen("queue.in","r",stdin); freopen("queue.out","w",stdout); n=rd(); build(1,1,n); for(int i=1;i<=n;i++){ a[i].x=rd();a[i].y=rd(); } sort(a+1,a+1+n); for(int i=n;i>=1;i--){ if(a[i].y>=n-i+1) return puts("impossible"),0; } for(int i=1;i<=n;i++){ update(1,1,n,min(a[i].y+1,n-i-a[i].y+1),a[i].x); } for(int i=1;i<=n;i++) cout<<elm[lef[i]]<<" "; return 0; }