首页 > 其他 > 详细

poj 2828 Buy Tickets

时间:2015-07-19 13:09:32      阅读:183      评论:0      收藏:0      [点我收藏+]

这题没思路,看别人题解

由于最后一个人插进来后他的位置肯定是固定的 我们就可以倒着来插

用sum[]数组表示改线段空位置的个数,满足 pos<=sum[rt<<1](即左儿子的空位多于插入数的位置序号)就访问左儿子,否则访问右儿子

(访问右节点的时候注意pos要修改,改为pos-sum[rt],即整个线段的第pos个空位,在下一个右儿子那的第pos-sum[rt]个空位)。

Problem: 2828		User: shu_dayang
Memory: 4536K		Time: 1500MS
Language: C++		Result: Accepted



#include<iostream>
#include<cstdio>
#include<cstring>
#define MID(a,b)  ((a + b) >> 1)
using namespace std;

const int MAXN = 200010;

int sum[MAXN << 2],p[MAXN],pos[MAXN],val[MAXN];

void PushUp(int rt)
{
    sum[rt] = sum[rt << 1] + sum[(rt << 1) + 1];
}

void build(int l, int r, int rt)
{
    if(l == r)
    {
        sum[rt] = 1;
        return;
    }
    int mid = MID(l, r);
    build(l, mid, rt << 1);
    build(mid + 1, r, (rt << 1) + 1);
    PushUp(rt);
}

void update(int pos,int val, int l, int r, int rt)
{
    if(l == r)
    {
        p[l] = val;
        sum[rt] --;
        return;
    }
    int mid = MID(l, r);
    if(pos <= sum[rt << 1])
        update(pos, val, l, mid, rt << 1);
    else
        update(pos - sum[rt << 1], val, mid + 1, r, (rt << 1) + 1);
    PushUp(rt);
}

int main()
{
    int n,i;
    while(~scanf("%d",&n))
    {
        build(1,n,1);
        for(i = 0; i < n; i++)
            scanf("%d%d",&pos[i],&val[i]);

        for(i = n - 1; i >= 0; i--)
            update(pos[i] + 1,val[i],1,n,1);

        for(i = 1; i< n ; i++)
            printf("%d ",p[i]);
        printf("%d\n",p[i]);
    }
}

 

poj 2828 Buy Tickets

原文:http://www.cnblogs.com/yong-hua/p/4658498.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!