PKU 2828 Buy Tickets

从后往前逐个添加,每次放到第pos[i]+1个空位置上;

维护区间内空位置的个数,修改和查询都是二分查找。

 1 # include <stdio.h>

 2 

 3 # define ls ((r)<<1)

 4 # define rs ((r)<<1|1)

 5 # define mid (((x)+(y))>>1)

 6 

 7 # define MAXN 200010

 8 

 9 int p[MAXN], v[MAXN], a[MAXN];

10 int sum[4 * MAXN];

11 

12 void build(int x, int y, int r)

13 {

14     sum[r] = y-x+1;

15     if (x == y) return ;

16     build(x, mid, ls);

17     build(mid+1, y, rs);

18 }

19 

20 void update(int r)

21 {

22     sum[r] = sum[ls] + sum[rs];

23 }

24 

25 void change(int x, int y, int r, int pos)

26 {

27     if (x == y)

28     {

29         sum[r] = 0;

30         return ;

31     }

32     if (pos <= mid) change(x, mid, ls, pos);

33     else change(mid+1, y, rs, pos);

34     update(r);

35 }

36 

37 void query(int x, int y, int r, int cnt, int *t)

38 {

39     if (x == y)

40     {

41         *t = x;

42         return ;

43     }

44     if (sum[ls] < cnt) query(mid+1, y, rs, cnt-sum[ls], t);

45     else query(x, mid, ls, cnt, t);

46 }

47 

48 int main()

49 {

50     int n, i, t;

51         

52     while (~scanf("%d", &n))

53     {

54         build(1, n, 1);

55         for (i = 1; i <= n; ++i) {scanf("%d%d", &p[i], &v[i]); a[i] = -1;}

56         for (i = n; i >= 1; --i)

57         {

58             query(1, n, 1, p[i]+1, &t);

59             a[t] = v[i];

60             change(1, n, 1, t);

61         }

62         printf("%d", a[1]);

63         for (i = 2; i <= n; ++i) printf(" %d", a[i]);

64         putchar('\n');

65     }

66     

67     return 0;

68 }

 

你可能感兴趣的:(pku)