[POJ2828] Buy Tickets(待續)
阿新 • • 發佈:2018-09-03
查找 測試 形象 順序 的人 就是 信息 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(待續)