Buy Tickets POJ - 2828线段树求插队

题意就是给你n个人,每个人有自己的要插入的pos和val,问你最后的排序

思路:逆序插入,最后一个人的位置一定是固定的,因为必须连续插入,所以第i个人插入的时候必须保证前面有pos[i]个空位,

那么用线段树记录位置个数,如果位置不够,就往后挪。

#include<iostream>
#include<cstdio>
using namespace std;

#define N 200005

int spare[N<<2];
int seq[N];
int pos[N],val[N];

void pushdown(int rt)
{
        spare[rt]=spare[rt*2]+spare[rt*2+1];
}
void build(int rt,int l,int r)
{
        if(l==r)
        {
                spare[rt]=1;
                return;
        }
        int mid=(l+r)/2;
        build(rt*2,l,mid);
        build(rt*2+1,mid+1,r);
        pushdown(rt);
}
void insert(int pos,int val,int rt,int l,int r)
{
        if(l==r)
        {
                seq[l]=val;
                spare[rt]=0;
                return;
        }
        int mid=(l+r)/2;
        if(pos<spare[rt*2])
        {
                insert(pos,val,rt*2,l,mid);
        }
        else
        {
                insert(pos-spare[rt*2],val,rt*2+1,mid+1,r);
        }
        pushdown(rt);
}
int main()
{

    int n;
    while(~scanf("%d",&n))
    {
        build(1,1,n);
        for (int i=0; i<n ; i++ )
        {
                scanf("%d %d",&pos[i],&val[i]);
        }
        for (int i=n-1;i>=0 ;i-- )
        {
                insert(pos[i],val[i],1,1,n);
        }
        for (int i=1;i<=n ;i++ )
        {
                if(i==n)
                {
                        printf("%d\n",seq[i]);
                }
                else
                printf("%d ",seq[i]);
        }
    }
    return 0;

}

猜你喜欢

转载自www.cnblogs.com/Json-Five/p/9821732.html