1. 程式人生 > >POJ2828 Buy Tickets 樹狀數組

POJ2828 Buy Tickets 樹狀數組

difficult cloc hint ood ima images PE size ger

Description

Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue…

The Lunar New Year was approaching, but unluckily the Little Cat still had schedules going here and there. Now, he had to travel by train to Mianyang, Sichuan Province for the winter camp selection of the national team of Olympiad in Informatics.

It was one o’clock a.m. and dark outside. Chill wind from the northwest did not scare off the people in the queue. The cold night gave the Little Cat a shiver. Why not find a problem to think about? That was none the less better than freezing to death!

People kept jumping the queue. Since it was too dark around, such moves would not be discovered even by the people adjacent to the queue-jumpers. “If every person in the queue is assigned an integral value and all the information about those who have jumped the queue and where they stand after queue-jumping is given, can I find out the final order of people in the queue?” Thought the Little Cat.

Input

There will be several test cases in the input. Each test case consists of N + 1 lines where N (1 ≤ N ≤ 200,000) is given in the first line of the test case. The next N lines contain the pairs of values Posi and Vali in the increasing order of i (1 ≤ iN). For each i, the ranges and meanings of Posi

and Vali are as follows:

  • Posi ∈ [0, i − 1] — The i-th person came to the queue and stood right behind the Posi-th person in the queue. The booking office was considered the 0th person and the person at the front of the queue was considered the first person in the queue.
  • Vali ∈ [0, 32767] — The i-th person was assigned the value Vali.

There no blank lines between test cases. Proceed to the end of input.

Output

For each test cases, output a single line of space-separated integers which are the values of people in the order they stand in the queue.

Sample Input

4
0 77
1 51
1 33
2 69
4
0 20523
1 19243
1 3890
0 31492

Sample Output

77 33 69 51
31492 20523 3890 19243

Hint

The figure below shows how the Little Cat found out the final order of people in the queue described in the first test case of the sample input.

技術分享圖片

Source

POJ Monthly--2006.05.28, Zhu, Zeyuan 提交地址 : Buy Tickets 題目大意 : 來了n個人, 每個人在隊列裏選擇了一個位置插入, 問最後的序列是什麽樣的; 分析: 時光倒流:因為最後的人肯定是站在自己想占的地方, 所以從後往前便於處理; 首先設一個人都沒有, 序列全部為1(後面講為什麽); 然後插入最後一個人, 那樣例二來說, 他肯定是插在了自己想在的地方, 所以把他所站的地方設為0, 序序列便成為了 0 1 1 1; 然後考慮倒數第二個人, 他要去第二的位置但是在他之前已經插入了最後一個人, 所以他最終的位置一定不是在第二個位置; 那是在第幾個位置呢? 答案是:第二個1!為什麽, 因為1表示此位置還未被占, 所以他要站在第二個沒有被占得位置上; 求前綴1的值我們可以用樹狀數組維護(這就是初始值是1的原因!); 但是對於沒個人都要枚舉一遍顯然是不現實的, 又因為前綴和滿足單調性, 所以直接暴力二分OK; 應該特別好理解; 不理解的看看代碼就差不多了; 代碼奉上: 技術分享圖片
//By zZhBr
#include <iostream>
#include <cstdio> 
#include <algorithm>
using namespace std;

int n;


struct pro
{
    int pos;
    int num;
}pr[200010];

int ans[200010];

int tr[200010];

int lowbit(int x)
{
    return x & -x;
}

void add(int x, int y)
{
    while(x <= n)
    {
        tr[x] += y;
        x += lowbit(x);
    }
}

int sum(int x)
{
    int ans = 0;
    while(x != 0)
    {
        ans += tr[x];
        x -= lowbit(x);
    }
    return ans;
}

int main()
{
    while(scanf("%d", &n) != EOF)
    {
        for(register int i = 1 ; i <= n ; i ++) ans[i] = 0;
        for(register int i = 1 ; i <= n ; i ++)
        {
            scanf("%d%d", &pr[i].pos, &pr[i].num);
            add(i, 1);
        }
        
        for(register int i = n ; i >= 1 ; i --)
        {
            int p = pr[i].pos + 1;
            
            if(sum(p) == p)
            {
                ans[p] = pr[i].num;
                add(p, -1);
                continue;
            }
            
            int l = p, r = n;
            while(l  < r)
            {
                int mid = l + r >> 1;
                if(sum(mid) >= p) r = mid;
                else l = mid + 1;
            }
            
            ans[l] = pr[i].num;
            add(l, -1);
            
        }
        
        for(register int i = 1 ; i <= n ; i ++)
        {
            printf("%d ", ans[i]);
        }
        printf("\n");
        
    }
    return 0;
}
zZhBr

POJ2828 Buy Tickets 樹狀數組