题目:http://poj.org/problem?id=2828
大意:有n个人买票,可以插队,给出每个人插队的位置和自己的价值,posi和vali,,posi表示这个人插在为位置在posi的人的后面,售票处的位置是0;问最后的队列顺序;
思路:从最后一个人往前插,posi值就代表这个人前面的空位数;
代码:
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=200100; 7 struct node 8 { 9 int pos; 10 int val; 11 }st[maxn]; 12 int tree[maxn*4]; 13 int res[maxn]; 14 void updatesum(int w) 15 { 16 tree[w]=tree[w*2]+tree[w*2+1]; 17 } 18 void build(int l,int r,int w) 19 { 20 tree[w]=0; 21 if(l==r-1) 22 { 23 tree[w]=1; 24 return ; 25 } 26 int m=(l+r)/2; 27 build(l,m,w*2); 28 build(m,r,w*2+1); 29 updatesum(w); 30 } 31 void update(int pos,int val,int l,int r,int w) 32 { 33 if(l==r-1) 34 { 35 tree[w]=0; 36 res[l]=val; 37 return ; 38 } 39 int m=(l+r)/2; 40 if(pos<tree[w*2]) 41 update(pos,val,l,m,w*2); 42 else 43 update(pos-tree[w*2],val,m,r,w*2+1); 44 updatesum(w); 45 } 46 int main() 47 { 48 int n; 49 while(scanf("%d",&n)!=EOF) 50 { 51 int i; 52 for(i=0;i<n;i++) 53 { 54 scanf("%d%d",&st[i].pos,&st[i].val); 55 } 56 memset(tree,0,sizeof(tree)); 57 build(0,n+1,1); 58 for(i=n-1;i>=0;i--) 59 { 60 61 update(st[i].pos,st[i].val,0,n+1,1); 62 } 63 for(i=0;i<n-1;i++) 64 { 65 printf("%d ",res[i]); 66 } 67 printf("%d ",res[n-1]); 68 } 69 return 0; 70 }