POJ2828 Buy Tickets
题意:一些人插队,按先后顺序给出来的人 要站的位置 和 他的编号,求解插队活动结束之后,从队头到队尾人的排列顺序
解法:对于任何一个人,他插队之后站的位置是a,如果他之后有一个人插到他前面,他就成了a+1,但是他前边的空位不会因为有人插到前边而改变,因此,从后向前来依次考虑每个人前边的空位个数。使用线段树来记录区间空位总数。
View Code
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <cmath> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; int pers[200005<<2],n,ans[200005],input_p[200005],input_v[200005]; void build(int l,int r,int rt) { pers[rt]=r-l+1; if (l==r) return; int m=(l+r)>>1; build(lson); build(rson); } int query(int p,int l,int r,int rt) { int ret; pers[rt]--; if (l==r) { return l; } int m=(l+r)>>1; if (p<=pers[rt<<1]) ret=query(p,lson); else ret=query(p-pers[rt<<1],rson); return ret; } int main() { while (~scanf("%d",&n)) { build(0,n-1,1); for (int i=1;i<=n;++i) scanf("%d%d",&input_p[i],&input_v[i]); for (int i=n;i>=1;--i) ans[query(input_p[i]+1,0,n-1,1)]=input_v[i]; for (int i=0;i<n-1;++i) printf("%d ",ans[i]); printf("%d\n",ans[n-1]); } }

浙公网安备 33010602011771号