POJ 2828 Buy Tickets 线段树
这道题要从后往前插入元素,最后一个元素的位置可以直接确定,倒数第i个的位置可以根据倒数i-1个的位置推测出来
线段树存储的是区间剩余的空位置。
#include <iostream> #include <cstdio> #include <cstring> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; const int MAXN = 200008; int lft[MAXN<<2], ans[MAXN]; int pos[MAXN], val[MAXN]; void build(int l, int r, int rt) { lft[rt] = r - l + 1; if(l == r) return; int m = (l + r) >> 1; build(lson); build(rson); } void update(int p, int i, int l, int r, int rt) { lft[rt]--; if(l == r) { ans[l] = val[i]; return; } int m = (l + r) >> 1; if(lft[rt<<1] >= p) update(p, i, lson); else update(p-lft[rt<<1], i, rson); //前面没有p个位置,就要往后推 } int main() { // freopen("in.txt","r",stdin); int n; while(~scanf("%d", &n)) { for(int i=0; i<n; i++) scanf("%d%d", &pos[i], &val[i]); build(1, n, 1); for(int i=n-1; i>=0; i--) update(pos[i]+1, i, 1, n, 1); for(int i=1; i<=n; i++) printf("%d%c", ans[i], i == n? '\n':' '); } return 0; }