POJ_2828 Buy Tickets 【线段树】

一、题目

  Buy Tickets

二、分析

  首先可以明确的是每个人的位置都是定的,那么如果从输入数据从后往前看,最后面的人进来的时候,他前面的人数肯定是定的。

  那么可以考虑,当从后往前推时,这个人插入的位置就是他前面有多少空位,假设他的位置比空位数少,那显然是不可以的,如果他的位置比空位多,那么后面的已经插入的,没有人来补这个位置了,所以显然也不合理,所以假设区间$[1,t]$刚好有$pos+1$个空位,那么它的位置应该就在最后一个空位处。

三、AC代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 
 8 using namespace std;
 9 #define ll long long
10 #define Min(a,b) ((a)>(b)?(b):(a))
11 #define Max(a,b) ((a)>(b)?(a):(b))
12 #define P pair<int, int>
13 #define lson (rt<<1)
14 #define rson (rt<<1|1)
15 const int MAXN = 2e5;
16 int ans[MAXN + 13];
17 int sum[MAXN<<2];   //表示区间内还有多少个位置
18 
19 void Build(int rt, int l, int r)
20 {
21     sum[rt] = r - l + 1;
22     if(l == r) {
23         sum[rt] = 1;
24         return;
25     }
26     int mid = (l + r) >> 1;
27     Build(lson, l, mid);
28     Build(rson, mid + 1, r);
29 }
30 
31 void Update(int rt, int l, int r, int pos, int val)
32 {
33     if(l == r) {
34         sum[rt] = 0;
35         ans[l] = val;
36         return;
37     }
38     int mid = (l + r) >> 1;
39     if(pos <= sum[lson])
40         Update(lson, l, mid, pos, val);
41     else
42         Update(rson, mid + 1, r, pos - sum[lson], val);
43     sum[rt]--;
44 }
45 
46 int main()
47 {
48     //freopen("input.txt", "r", stdin);
49     int N;
50     while(scanf("%d", &N) != EOF) {
51         int a, b;
52         Build(1, 1, N);
53         vector<P> vec;
54         for(int i = 0; i < N; i++) {
55             scanf("%d%d", &a, &b);
56             vec.push_back(P(a, b));
57         }
58         for(int i = vec.size()-1; i >= 0; i--) {
59             Update(1, 1, N, vec[i].first + 1, vec[i].second);
60         }
61         for(int i = 1; i <= N; i++) {
62             printf("%d%c", ans[i], i == N ? '\n' : ' ');
63         }
64 
65     }
66     return 0;
67 }

 

posted @ 2019-08-29 12:16  Dybala21  阅读(105)  评论(0编辑  收藏  举报