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

    题目:poj 2828 Buy Tickets


    题意:有n个人排队,每一个人有一个价值和要插的位置,然后当要插的位置上有人时全部的人向后移动一位当这个插入到这儿,假设没有直接插进去。


    分析:分析发现直接插入移动的话花时间太多。我们可不能够用逆向思维。

    从后往前来。由于最后一个位置是肯定能确定的,而其它的则插入空的第某个位置。

    比方第一组例子:

    4
    0 77
    1 51
    1 33
    2 69

    開始时候位置都为空 编号0 1 2 3

    首先从最后一个来2 69

    第二个位置空,则能够直接放

    然后编号变为0 1 69 2

    接着放1 33

    编号变为 0 33 69 1

    然后放1 51

    编号变为0 33 69 51

    然后放最后一个0 77

    则最后结果为 77 33 69 51


    能够发现该怎么搞了。就是直接用线段树来维护区间上的值。然后选择插入对应的位置就可以。

    AC代码:


    #include <cstdio>
    #include <vector>
    #include <iostream>
    using namespace std;
    typedef long long LL ;
    const int N = 220000;
    
    struct Node
    {
        int l,r;
        int val,num;
    };
    Node tree[5*N];
    void build(int o,int l,int r)
    {
        tree[o].l = l,tree[o].r = r;
        if(l==r)
        {
            tree[o].val = 1;
            return ;
        }
        int mid = (l+r)/2;
        build(o+o,l,mid);
        build(o+o+1,mid+1,r);
        tree[o].val = tree[o+o].val + tree[o+o+1].val;
    }
    void update(int o,int num,int val)
    {
        //printf("%d %d %d %d
    ",o,tree[o].l,tree[o].r,tree[o].val);
        if(tree[o].l==tree[o].r)
        {
            tree[o].num = val;
            tree[o].val = 0;
            return ;
        }
        if(tree[o+o].val>=num)
            update(o+o,num,val);
        else
            update(o+o+1,num-tree[o+o].val,val);
        tree[o].val = tree[o+o].val + tree[o+o+1].val;
    }
    vector<int> ans;
    void Yougth(int o)
    {
        if(tree[o].l==tree[o].r)
        {
            ans.push_back(tree[o].num);
            return ;
        }
        Yougth(o+o);
        Yougth(o+o+1);
    }
    pair <int,int> p[N];
    int main()
    {
        //freopen("Input.txt","r",stdin);
        int n;
        while(~scanf("%d",&n))
        {
            build(1,1,n);
            for(int i=0;i<n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                x++;
                p[i] = make_pair(x,y);
            }
            for(int i=n-1;i>=0;i--)
                update(1,p[i].first,p[i].second);
            Yougth(1);
            for(int i=0;i<ans.size();i++)
                printf("%d%c",ans[i],i==(ans.size()-1)?'
    ':' ');
            ans.clear();
        }
        return 0;
    }
    


  • 相关阅读:
    测试软件—禅道BUG管理工具
    C语言 线性表的操作~(未完)
    数据库考纲~
    圣杯布局和双飞翼布局总局
    总结布局用法
    springboot~入门第三篇~与mybatis整合~(未完)
    微信小程序里 wx:for和wx:for-item区别(补充下wx:key)
    对比下小程序语法和Vue语法异同
    视频转换 rtsp 流 转rtmp流播放(待完善)
    Vue钩子函数~
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6869088.html
Copyright © 2011-2022 走看看