zoukankan      html  css  js  c++  java
  • 线段树端点更新 poj 2828 Buy Tickets

    题目链接:

    http://poj.org/problem?id=2828

    题目意思:

    有n个人排队,每个人有个pos值,和value值,表示他可以插到第pos个人的后面,输出最后的队形序列。

    解题思路:

    如果顺着插的话,要移动后面的队列,如果用链表的话,找到插入的位置很费时。

    如果逆着考虑的话,当前的人插到恰好有pos个空位的最小的地方,就很简单。

    用线段树维护区间内空位的个数,如果要求的空位数大于左边区间的空位数,则减去左边的空位数,再在右边查找。

    总结:抽象出线段树维护的空间很重要。

    代码:

    //如果逆着推的话,就不用移动很多元素了,这是关键,
    //用线段树维护区间的空位数,如果左边的空位数不够的话,选择右边(其中把左边占满),知道找到插入的位置
    //线段树 抽象出维护的空间 很关键
    
    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<stack>
    #include<list>
    #include<queue>
    #define eps 1e-6
    #define INF (1<<30)
    #define PI acos(-1.0)
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define maxn 210000
    
    int sum[maxn*4];
    int pos[maxn],value[maxn],ans[maxn],n;
    int temp;
    /*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    */
    void build(int l,int r,int rt)
    {
        sum[rt]=r-l+1; //初始区间空位的多少
        if(r==l)
            return ;
        int m=(l+r)>>1;
    
        build(lson);
        build(rson);
    }
    
    void update(int target,int l,int r,int rt)
    {
        sum[rt]--;   //所到之处,空位数减一,因为必须在某个区间插
        if(l==r)
        {
            temp=l; //找到空位的位置,记住然后进行插入
            return ;
        }
    
        int m=(l+r)>>1;
    
        if(target<=sum[rt<<1])  //如果左区间的空位数够的话,在左区间更新
            update(target,lson);
        else
            update(target-sum[rt<<1],rson); //左区间不够,先把左区间占满,然后在填右区间
        return ;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1;i<=n;i++)
                scanf("%d%d",&pos[i],&value[i]);
            build(1,n,1);
    
            for(int i=n;i>=1;i--)
            {
                update(pos[i]+1,1,n,1);
                ans[temp]=value[i];  //把位置找到然后插入
            }
            printf("%d",ans[1]);
            for(int i=2;i<=n;i++)
                printf(" %d",ans[i]);
            putchar('\n');
        }
        return 0;
    }
    
    


     

  • 相关阅读:
    Python python __def__ Exception AttributeError: "'NoneType' object has no attribute
    Python sys.argv[]用法
    Python 编写通过DOS压缩的例子遇到的几个问题
    DOS rar压缩
    Oracle游标介绍
    C#保存日志文件到txt中,可追加保存,定时删除最后一次操作半年前日志文件
    VS2008生成解决方案卡顿、龟速
    VS工具箱中添加DevExpress控件
    CLR 无法从 COM 上下文 0x208f68 转换为 COM 上下文 0x2090d8,这种状态已持续 60 秒
    命名空间"xx"已经包含了"xx"的定义
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/2999168.html
Copyright © 2011-2022 走看看