线段树 逆序 单点更新 PKU 2828

Buy Tickets

Time Limit: 4000MS   Memory Limit: 65536K
Total Submissions: 14077   Accepted: 7060

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

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

从最后一个人开始考虑

//记录每个节点的可以存放的个数
//从最后的一个人开始考虑,每次把一个人的位置确定好之后就把这个位置丢掉
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAXN 200000 + 100
int con[MAXN<<2];
int ans[MAXN];
int a[MAXN];
int b[MAXN];

void build(int l,int r,int rt){
    con[rt] = r-l+1;
    if(l == r){
        return ;
    }
    int m = (l+r)/2;
    build(lson);
    build(rson);
}

void update(int n,int l,int r,int rt){
    con[rt]--;
    if(l == r){
        ans[r] = b[n];
        return ;
    }
    int m = (l+r)/2;
    if(con[rt<<1]>=a[n]){
        update(n,lson);
    }
    else{
        a[n]-=con[rt<<1];
        update(n,rson);
    }
}

int main(){
    int n,i;

    while(~scanf("%d",&n)){
        memset(con,0,sizeof(con));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(ans,0,sizeof(ans));
        for(i=1;i<=n;i++){
            scanf("%d%d",&a[i],&b[i]);
            a[i]++;
        }
        build(1,n,1);
        for(i=n;i>=1;i--){
            update(i,1,n,1);
        }
        for(i=1;i<=n;i++){
            if(i != n){
                printf("%d ",ans[i]);
            }
            else{
                printf("%d\n",ans[i]);
            }
        }
    }

    return 0;
}
时间: 2024-10-14 01:48:06

线段树 逆序 单点更新 PKU 2828的相关文章

POJ2828 Buy Tickets 【线段树】+【单点更新】+【逆序】

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 12296   Accepted: 6071 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 wa

hdu 4893 Wow! Such Sequence!(线段树功能:单点更新,区间更新相邻较小斐波那契数)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 --------------------------------------------------------------------------------------------------------------------------------------------

POJ2886 Who Gets the Most Candies? 【线段树】+【单点更新】+【模拟】+【反素数】

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9416   Accepted: 2868 Case Time Limit: 2000MS Description N children are sitting in a circle to play a game. The children are numbered from 1 to N in clockwise o

HDU2795 Billboard 【线段树】+【单点更新】

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9632    Accepted Submission(s): 4286 Problem Description At the entrance to the university, there is a huge rectangular billboard of s

hdu 1116 敌兵布阵 线段树 区间求和 单点更新

线段树的基本知识可以先google一下,不是很难理解 线段树功能:update:单点增减 query:区间求和 #include <bits/stdc++.h> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; const int MAXN = 50008; int sum[MAXN<<2]; void build(int l, int r, int rt)

POJ 2828——Buy Tickets(树状数组,线段树——逆序遍历)

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 13496   Accepted: 6726 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 wa

线段树入门之单点更新

作者:zifeiy 标签:线段树 单点更新 :最最基础的线段树,只更新叶子节点,然后把信息用 push_up(int rt) 这个函数更新上来 HDU1166 敌兵布阵 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 线段树功能: update:单点增减: query:区间求和 #include <bits/stdc++.h> using namespace std; #define lson l, m, rt<<1 #def

HDU(1166),线段树模板,单点更新,区间总和

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 第一次做线段树,帆哥的一句话,我记下来了,其实,线段树就是一种处理数据查询和更新的手段. 然后,我的代码风格,是网上的大牛们的辛苦总结,我就套用了.这里,我还是简单说一下线段树,说的不好,主要方便自己复习. 线段树,3个步骤,建树,查询,更新, 建树:到底部就是a[]数组的值,建立左右子树后,向上推根,根为左右子树的值 更新:类似建树,二分,找到单点所在区间,更新该区间,记得上一个区间也要变化

nyoj 119 士兵杀敌(三) 【线段树】【单点更新】

题意:... 策略如题. 思路:我们先假设只求某一区间的最大值,我们只需要利用线段树的模板,只需要初始化和询问的时候小小的修改一下,改成祖先结点储存的不再是子节点的和而是两个子节点之间的最大值,这样我们可以求出最大值了,最小值也是这样求. 注意:因为询问的时候既要求最大值又要求最小值,所以要返回结构体. 代码: #include <stdio.h> #include <string.h> #define M 100005 struct node{ int left, right;