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;
}

 

posted @ 2017-08-18 11:13  Pacify  阅读(141)  评论(0编辑  收藏  举报