hdu 2828 Buy Tickets 线段树

最后的人的位置一定是固定的,所以倒序插入,插入之后这个位置就不参与计数了,所以问题变成,找到第 i 个空位,线段树记录该区间里有几个空位。

#include <stdio.h>
#define maxn 200010
int sum[4*maxn];
int pos[maxn],val[maxn];
int ans[maxn];
void pushup(int o)
{
    sum[o]=sum[o*2]+sum[o*2+1];
}
void build(int l,int r,int o)
{
    if(l==r)
    {
        sum[o]=1;
        return;
    }
    else
    {
        int m=(l+r)/2;
        build(l,m,o*2);
        build(m+1,r,o*2+1);
        pushup(o);
    }
}
int query(int p,int l,int r,int o)
{
    if(l==r)
    {
        sum[o]=0;
        return l;
    }
    else
    {
        int m=(l+r)/2,rank;
        if(sum[o*2]>p) rank=query(p,l,m,o*2);
        else rank=query(p-sum[o*2],m+1,r,o*2+1);
        pushup(o);
        return rank;
    }
}
int main()
{
    int n;
    int i;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%d%d",&pos[i],&val[i]);
        build(0,n-1,1);
        for(i=n;i>0;i--)
        {
            int x=query(pos[i],0,n-1,1);
            ans[x]=val[i];
            //printf("%d %d\n",x,val[i]);
        }
        printf("%d",ans[0]);
        for(i=1;i<n;i++) printf(" %d",ans[i]);
        printf("\n");
    }
    return 0;
}


 

posted @ 2014-05-17 18:49  贝尔摩德  阅读(128)  评论(0编辑  收藏  举报