• 洛谷 P1801 黑匣子_NOI导刊2010提高(06)


    P1801 黑匣子_NOI导刊2010提高(06)

    法一:算法思想较精妙--两个堆

    先将数字放入大根堆,然后取出堆顶元素,放入小根堆,如果要求输出,则取出小根堆堆顶元素,输出并放入大根堆。

    如何得出的呢?

    先从简单的开始:

    若当前已经add了x-1个数,将要add第x个数并查询,还未进行过查询,那么将x放入后,小根堆中应该是从小到大排好的所有数,则会输出最小的数并将其放入大根堆。

    若还要add第x+1个数,并进行第2次查询,那么大根堆堆顶会是"1~x个数中最小的那个数"还有"x+1个数"中较大的那个,将其取出并放入小根堆后,显然1~x+1个数中最小的那个还在大根堆中,那么小根堆堆顶就是第2小的数了。

    若还要add一些数,但是不查询,那么显然,不管怎么add,所有数中最小的2个永远会被留在大根堆中,小根堆堆顶永远是第3小的。

    若这之后要查询,那么以后再add时就能确保所有数中最小的3个永远会被留在大根堆中,小根堆堆顶永远是第4小的。

    ......

    按照这样类比,很容易知道解法。

    #include<cstdio>
    #include<queue>
    using namespace std;
    priority_queue<int> q1;//大根堆 
    priority_queue<int,vector<int>,greater<int> > q2;//小根堆 
    int m,n;
    int a[300000];
    int main()
    {
        int i,j,k,p;
        scanf("%d%d",&m,&n);
        for(i=1;i<=m;i++)
            scanf("%d",&a[i]);
        int s=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&k);
            while(s<k)
            {
                q1.push(a[++s]);
                p=q1.top();
                q1.pop();
                q2.push(p);
            }
            p=q2.top();
            q2.pop();
            printf("%d
    ",p);
            q1.push(p);
        }
        return 0;
    }

    题解里有一种类似的:


    题解

    法二:数据结构--平衡树

  • 相关阅读:
    使用NPOI将多张图片导入execl
    Oracle计算时间差函数
    Oracle_spatial的函数介绍[转]
    FDO error:Failed to label layer(XXX) for class Default
    您属于哪个版本的程序员[转]
    关于oracle-12514错误的修改方法
    ArcGis在Oracle中常用的sql
    读取XML绑定TreeNode
    HTML中图片热区的使用
    如何查看目前正在使用的Windows10是哪个版本?
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8470453.html
Copyright © 2020-2023  润新知