poj 2828 Buy Tickets(线段树)

题目: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\n",res[n-1]);
68     }
69     return 0;
70 }
View Code

 

 

posted @ 2013-06-16 21:58  琳&leen  阅读(209)  评论(0编辑  收藏  举报