线段树(单点更新) POJ 2828 Buy tickets

题目传送门

 1 /*
 2     结点存储下面有几个空位
 3     每次从根结点往下找找到该插入的位置,
 4     同时更新每个节点的值
 5 */
 6 #include <cstdio>
 7 #define lson l, m, rt << 1
 8 #define rson m+1, r, rt << 1 | 1
 9 
10 const int MAX_N = 200000 + 10;
11 int pos[MAX_N], val[MAX_N];
12 int sum[MAX_N << 2];
13 int que[MAX_N];
14 int id;
15 
16 void build(int l, int r, int rt)
17 {
18     sum[rt] = r - l + 1;        //节点有多少个空位置
19     if (l == r)        return ;
20     int m = (l + r) >> 1;
21     build (lson);
22     build (rson);
23 }
24 
25 void update(int p, int l, int r, int rt)
26 {
27     sum[rt]--;                    //插入一个减少一个空位置
28     if (l == r)                    //找到了传递该位置
29     {
30         id = l;
31         return ;
32     }
33     int m = (l + r) >> 1;
34     if (p <= sum[rt<<1])
35     {
36         update (p, lson);
37     }
38     else
39     {
40         p -= sum[rt<<1];    //减去
41         update (p, rson);
42     }
43 }
44 
45 int main(void)        //POJ 2828 Buy tickets
46 {
47     //freopen ("inE.txt", "r", stdin);
48     int n;
49 
50     while (~scanf ("%d", &n))
51     {
52         build (1, n, 1);
53         for (int i=1; i<=n; ++i)
54         {
55             scanf ("%d%d", &pos[i], &val[i]);
56         }
57         for (int i=n; i>=1; --i)        //最后插入的位置不变
58         {
59             update (pos[i]+1, 1, n, 1);
60             que[id] = val[i];
61         }
62         printf ("%d", que[1]);
63         for (int i=2; i<=n; ++i)
64         {
65             printf (" %d", que[i]);
66         }
67         puts ("");
68     }
69 
70     return 0;
71 }
编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4506523.html