Buy Tickets POJ - 2828线段树求插队
题意就是给你n个人,每个人有自己的要插入的pos和val,问你最后的排序
思路:逆序插入,最后一个人的位置一定是固定的,因为必须连续插入,所以第i个人插入的时候必须保证前面有pos[i]个空位,
那么用线段树记录位置个数,如果位置不够,就往后挪。
#include<iostream> #include<cstdio> using namespace std; #define N 200005 int spare[N<<2]; int seq[N]; int pos[N],val[N]; void pushdown(int rt) { spare[rt]=spare[rt*2]+spare[rt*2+1]; } void build(int rt,int l,int r) { if(l==r) { spare[rt]=1; return; } int mid=(l+r)/2; build(rt*2,l,mid); build(rt*2+1,mid+1,r); pushdown(rt); } void insert(int pos,int val,int rt,int l,int r) { if(l==r) { seq[l]=val; spare[rt]=0; return; } int mid=(l+r)/2; if(pos<spare[rt*2]) { insert(pos,val,rt*2,l,mid); } else { insert(pos-spare[rt*2],val,rt*2+1,mid+1,r); } pushdown(rt); } int main() { int n; while(~scanf("%d",&n)) { build(1,1,n); for (int i=0; i<n ; i++ ) { scanf("%d %d",&pos[i],&val[i]); } for (int i=n-1;i>=0 ;i-- ) { insert(pos[i],val[i],1,1,n); } for (int i=1;i<=n ;i++ ) { if(i==n) { printf("%d\n",seq[i]); } else printf("%d ",seq[i]); } } return 0; }