POJ 2828 Buy Tickets 线段树
题目: http://poj.org/problem?id=2828
很巧妙的题,逆序插入线段树,这样元素不用移动。用二叉排序树也能过。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 4 const int MAXN = 200010; 5 6 int pos[MAXN], val[MAXN], ans[MAXN]; 7 8 struct Tree_Node 9 { 10 int left, right; 11 int num; 12 } tree[MAXN<<2]; 13 14 void build(int left, int right, int step) 15 { 16 tree[step].left = left; 17 tree[step].right = right; 18 tree[step].num = right - left + 1; 19 if(left == right) 20 { 21 return; 22 } 23 int mid = (left + right) >> 1; 24 build(left, mid, step<<1); 25 build(mid+1, right, step<<1|1); 26 } 27 28 void insert(int posi, int vali, int step) 29 { 30 tree[step].num--; 31 if(tree[step].left == tree[step].right) 32 { 33 ans[tree[step].left] = vali; 34 return; 35 } 36 if(posi < tree[step<<1].num) 37 insert(posi, vali, step<<1); 38 else 39 insert(posi - tree[step<<1].num, vali, step<<1|1); 40 } 41 42 int main() 43 { 44 int n; 45 while(scanf("%d", &n) != EOF) 46 { 47 build(0, n-1, 1); 48 for(int i = 0; i < n; i++) 49 scanf("%d %d", &pos[i], &val[i]); 50 for(int i = n-1; i >= 0; i--) 51 insert(pos[i], val[i], 1); 52 for(int i = 0; i < n-1; i++) 53 printf("%d ", ans[i]); 54 printf("%d\n", ans[n-1]); 55 } 56 return 0; 57 }