zoukankan      html  css  js  c++  java
  • 堆-动态的排序(洛谷1801-黑匣子)

    题目描述

    Black Box是一种原始的数据库。它可以储存一个整数数组,还有一个特别的变量i。最开始的时候Black Box是空的.而i等于0。这个Black Box要处理一串命令。

    命令只有两种:

    ADD(x):把x元素放进BlackBox;

    GET:i加1,然后输出Blackhox中第i小的数。

    记住:第i小的数,就是Black Box里的数的按从小到大的顺序排序后的第i个元素。例如:

    我们来演示一下一个有11个命令的命令串。(如下图所示)

    现在要求找出对于给定的命令串的最好的处理方法。ADD和GET命令分别最多200000个。现在用两个整数数组来表示命令串:

    1.A(1),A(2),…A(M):一串将要被放进Black Box的元素。每个数都是绝对值不超过2000000000的整数,M$200000。例如上面的例子就是A=(3,1,一4,2,8,-1000,2)。

    2.u(1),u(2),…u(N):表示第u(j)个元素被放进了Black Box里后就出现一个GET命令。例如上面的例子中u=(l,2,6,6)。输入数据不用判错。

    输入输出格式

    输入格式:

    第一行,两个整数,M,N。

    第二行,M个整数,表示A(l)

    ……A(M)。

    第三行,N个整数,表示u(l)

    …u(N)。

    输出格式:

    输出Black Box根据命令串所得出的输出串,一个数字一行。

    输入输出样例

    输入样例#1:
    7 4
    3 1 -4 2 8 -1000 2
    1 2 6 6
    
    输出样例#1:
    3
    3
    1
    2

    说明

    对于30%的数据,M≤10000;

    对于50%的数据,M≤100000:

    对于100%的数据,M≤200000。

    思路:不难想到求第i小需要堆排序。

    难点:难道每输出一个数,就要维护堆后重新堆排一遍?

    机关(优化):只需求第i小的(即对于第i小的这个元素之前是否按顺序排好无要求)。

    分析:堆的一个特点是只知最大(小)的那个元素,剩余位置较混乱;这也是它快的一个原因。

       【故求第i小,则可以建一个含i个元素的大根堆,堆顶即为所求】。

       而i个之外的元素可以放在另一个【小根堆】中,【以便向大根堆中补给】。

    难点:随着输入数的增多,第i小的值会不断变化。

       先把输入的数据都输完了,才输要求输出的数据;如何做到随时向那个大根堆中补给适当的数?

    思路:只需要将输入的数存入一个数组,就可以做到适时输入一样的效果,方便地取用。

    于是诞生了很快的代码(n·logn):

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,m,xnt1,xnt2,s=1;
    long long c,hp1[200005],hp2[200005],a[200005];//hp1为那个小根堆,hp2为那个大根堆
    void pus1(long long a)
    {
        xnt1++;
        hp1[xnt1]=a;
        int now=xnt1;
        while(now>1)
        {
            int tp=now/2;
            if(hp1[tp]>hp1[now])swap(hp1[tp],hp1[now]);
            else break;
            now=tp;
        }
    }
    void pus2(long long a)
    {
        xnt2++;
        hp2[xnt2]=a;
        int now=xnt2;
        while(now>1)
        {
            int tp=now/2;
            if(hp2[tp]<hp2[now])swap(hp2[tp],hp2[now]);
            else break;
            now=tp;
        }
    }
    long long del1()
    {
        long long res=hp1[1];
        hp1[1]=hp1[xnt1];
        xnt1--;
        int now=1;
        while(now*2<=xnt1)
        {
            int tp=now*2;
            if(tp<xnt1&&hp1[tp+1]<hp1[tp])tp++;
            if(hp1[tp]<hp1[now])swap(hp1[tp],hp1[now]);
            else break;
            now=tp;
        }
        return res;
    }
    long long del2()
    {
        long long res=hp2[1];
        hp2[1]=hp2[xnt2];
        xnt2--;
        int now=1;
        while(now*2<=xnt2)
        {
            int tp=now*2;
            if(tp<xnt2&&hp2[tp+1]>hp2[tp])tp++;
            if(hp2[tp]>hp2[now])swap(hp2[tp],hp2[now]);
            else break;
            now=tp;
        }
        return res;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        for(int i=1;i<=m;i++)
        {
            scanf("%lld",&c);
            for(;s<=c;s++)
            {
                if(!hp2[1])
                {
                    pus2(a[s]);continue;
                }
                if(a[s]>=hp2[1])pus1(a[s]);
                else
                {
                    if(xnt2==i)//原来xnt2是i-1,当已经进入过一个元素后,再要进入,就需调整
                        pus1(del2());//把原来的堆顶挤入hp1中
                    pus2(a[s]);
                }
            }
            if(xnt2<i)
                pus2(del1());//从hp1中取出一个放入hp2
            printf("%lld
    ",hp2[1]);
        }
    }
  • 相关阅读:
    realsense d435i qt 测试
    realsense d435i 数据 测试
    realsense d435i测试
    ubuntu torch GPU yolov5
    IfcLayeredItem
    ubuntu大服务器 pytorch环境配置
    condarc内容
    realsense point cloud
    yolov5 环境配置
    pip error
  • 原文地址:https://www.cnblogs.com/Narh/p/8032340.html
Copyright © 2011-2022 走看看