poj_2828 Buy Tickets(线段树)

来源:互联网 发布:网络监控服务器搭建 编辑:程序博客网 时间:2024/05/19 16:32
Buy Tickets
Time Limit: 4000MS Memory Limit: 65536KTotal Submissions: 19366 Accepted: 9586

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 ≤ i ≤ N). 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

40 771 511 332 6940 205231 192431 38900 31492

Sample Output

77 33 69 5131492 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.


n个人动态插入队列中,求最后队列排布。
直接思路是链表,不过很容易就超时了,
可以考虑从后往前倒推出队列排布,
首先最后一组数据一定是最后的排布,也就是第n-1人左边有pos(n-1)人,也可以说第n-1人在位置pos(n-1)上。
前面的数据可以通过已得出的位置来确定。
用线段树来保存某个区间内已填的人数cot[rt],如读取最后一组数据,区间[0, n-1]到区间[pos(n-1), pos(n-1)]所经过的区间的已填人数都加上1,
同时得出第n-1人的位置在pos(n-1)上。
那么之后第i人要填的位置就可以通过线段树中的cot[rt]和pos(i)来确定,
即更新线段树时同时判断,
当cot[rt<<1]+pos(i) <= m时,即在满足 第i人左边有pos(i)个人 的同时,左孩子还有空位可以放第i人,所以向左孩子移动,
当cot[rt<<1]+pos(i) > m时,即左孩子已经放不了第i人了,所以向右孩子移动,需要注意的是现在的pos(i)需要加上左孩子已填的人数cot[rt<<1],这样才能让pos(i)维持 第i人左边有pos(i)个人 的含义。
最后递归到叶子时得到的pos(i)即为所求。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 200010#define mod 1000000007#define PI acos(-1.0)#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;struct Node{    int l, r;    int mid(){ return l+r>>1; }}tree[maxn<<4];int cot[maxn<<4];int n;int val[maxn], pos[maxn];int ans[maxn];void build(int pos, int val, int l, int r, int rt){    tree[rt].l = l, tree[rt].r = r;    if(l <= pos && pos <= r) cot[rt] = 1;    else cot[rt] = 0;    if(l == r) { if(l == pos) ans[pos] = val; return ; }    int m = l+r>>1;    build(pos, val, lson);    build(pos, val, rson);}void update(int pos, int val, int rt){    if(tree[rt].l == tree[rt].r)    {        if(!cot[rt]) ans[pos] = val, cot[rt]++;        return ;    }    cot[rt]++;    int m = tree[rt].mid();    if(cot[rt<<1] + pos <= m) update(pos, val, rt<<1);    else update(pos+cot[rt<<1], val, rt<<1|1);}int main(){    while(~scanf("%d", &n))    {        for(int i = 0; i < n; i++) scanf("%d%d", &pos[i], &val[i]);        build(pos[n-1], val[n-1], 0, n-1, 1);        for(int i = n-2; i >= 0; i--) update(pos[i], val[i], 1);        for(int i = 0; i < n-1; i++) printf("%d ", ans[i]);        printf("%d\n", ans[n-1]);    }    return 0;}


0 0
原创粉丝点击