1. 程式人生 > >[POJ2828] Buy Tickets(待續)

[POJ2828] Buy Tickets(待續)

查找 測試 形象 順序 的人 就是 信息 eof 需要

[POJ2828] Buy Tickets(待續)

題目大意:多組測試,每組給出\(n\)條信息\((a,b)\),表示\(b\)前面有\(a\)個人,順序靠後的信息優先級高

Solution.1

由後向前看,每個遇到的都是確定位置的,最後的人選定的位置不會改變,同樣因為是倒敘輸入,在第\(i\)個人後插隊,也就是說他的前面一定要留下\(i\)個空格。

形象一點就是這樣:

技術分享圖片

從後往前,去查找第一個大於所需要空白的位置。用線段樹維護空格數目即可

Code.1

#include <iostream>
#include <cstdio>
#include <algorithm>

const int N = 2e5 + 10;

int n;
int a[N], b[N];
int num[N << 2], spa[N << 2];

inline void pushup(int cur){
    spa[cur] = spa[cur << 1] + spa[cur << 1 | 1];
    return;
} 

void build(int cur, int l, int r){
    int mid = l + ((r - l) >> 1);
    if(l == r){
        spa[cur] = 1;
        num[cur] = 0;
    }else{
        build(cur << 1, l, mid);
        build(cur << 1 | 1, mid + 1, r);
        pushup(cur);
    }
} 

void update(int cur, int l, int r, int la, int lb){
    if(l == r){
        spa[cur] = 0;
        num[cur] = lb;
    }else{
        int mid = l + ((r - l) >> 1);
        
        if(spa[cur << 1] >= la){
            update(cur << 1, l, mid, la, lb);
        }else{
            update(cur << 1 | 1, mid + 1, r, la - spa[cur << 1], lb);
        }
        pushup(cur);
    }
}

inline void print(int cur, int l, int r){
    int mid = l + ((r - l) >> 1);
    if(l == r){
        printf("%d ", num[cur]);
        return;
    }else{
        print(cur << 1, l, mid);

        print(cur << 1 | 1, mid + 1, r); 
    }
    return;
}

int main(){
    
    while(scanf("%d", &n) != EOF){
        build(1, 1, n);
        for(int i = 1; i <= n; ++i){
            scanf("%d %d", &a[i], &b[i]);
            a[i] ++;
        }
        for(int i = n; i; --i){
            update(1, 1, n, a[i], b[i]);
        }
        print(1, 1, n);
        printf("\n");
    }
    
    return 0;
}

Solution.2

用splay優雅接上

Code.2

[POJ2828] Buy Tickets(待續)