Buy Tickets(线段树) POJ - 2828

有N个人排队,每一个人都有一个val来对应,每一个后来人都会插入当前队伍的某一个位置pos。要求把队伍最后的状态输出。

第一行一个整数N,表示n个人 接下来n行,每行两个整数x和val,表示一个标记为val的人,插入到排在第x位置的人的后面。

从前往后,输出所有的val


思路:从后往前读入,记录当前行还有多少个位置没有插入。


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include <sstream>
#include<vector>
#include<cmath>    
#include<stack>
#include<time.h>
#include<ctime>
using namespace std;
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 10000005
int a[maxn] = {};
int b[maxn] = {};
int ans[maxn] = {};
struct node
{
    int L, R, num;
}tree[maxn];
void build(int root, int L, int R)
{
    tree[root].L = L;
    tree[root].R = R;
    tree[root].num = (R - L + 1);
    if (tree[root].L == tree[root].R)
    {
        return;
    }
    int mid = (L + R) >> 1;
    build(root << 1, L, mid);
    build(root << 1 | 1, mid + 1, R);
}
void update(int root, int step, int val)
{
    if (tree[root].L == tree[root].R)
    {    
        tree[root].num = 0;
        ans[tree[root].L] = val;
        return;
    }
    if (tree[root<<1].num >= step)//左子树剩余的位置大于或等于要放的位置 
    {
        update(root << 1, step, val);
    }
    else
    {
        update(root << 1 | 1, step - tree[root << 1].num, val);//要减去左子树的数目
    }
    tree[root].num = tree[root << 1].num + tree[root << 1 | 1].num;
}
int main()
{
    int n;
    while (~scanf("%d", &n))
    {
        build(1, 1, n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d", &a[i], &b[i]);
        }
        for (int i = n; i >= 1; i--)
        {
            update(1, a[i] + 1, b[i]);
        }
        for (int i = 1; i <= n; i++)
        {
            if (i == 1)
            {
                printf("%d", ans[i]);
            }
            else
            {
                printf(" %d", ans[i]);
            }
        }
        printf("\n");
    }
}

猜你喜欢

转载自www.cnblogs.com/whhh/p/13399112.html