码迷,mamicode.com
首页 > 其他好文 > 详细

题解 UVA501 【Black Box】

时间:2020-01-22 23:47:49      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:大于   href   set   使用   efi   can   amp   black   ace   

思路与中位数一题,解决方案比较像,使用对顶堆来解决。

具体实现为,使用两个堆,大根堆维护较小的值,小根堆维护较大的值,即小根堆的堆顶是较大的数中最小的,大根堆的堆顶是较小的数中最大的。

将大于大根堆堆顶的数(比所有大根堆中的元素都大)的数放入小根堆,小于等于大根堆堆顶的数(比所有小根堆中的元素都小)的数放入大根堆。

那么就保证了所有大根堆中的元素都小于小根堆中的元素。

如果将大根堆中元素个数维护为\(i\)个,那么就可以直接访问大根堆堆顶,来得到从小到大的顺序排序后的第\(i\)个元素了。

\(code\):

#include<bits/stdc++.h>
#define maxn 200100
using namespace std;
priority_queue<int,vector<int>,less<int> > b;//大根堆
priority_queue<int,vector<int>,greater<int> > s;//小根堆
int n,m;
int a[maxn],u[maxn];
int cur=1,ii;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        cur=1;
        ii=0;
        while(!b.empty())
        b.pop();
        while(!s.empty())
        s.pop();
        memset(a,0,sizeof(a));
        memset(u,0,sizeof(u));//清空
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
        for(int i=1;i<=m;++i)
        scanf("%d",&u[i]);
        for(int i=1;i<=n;++i)
        {
            if(b.empty())//ADD命令
            s.push(a[i]);
            else
            {
                if(a[i]<b.top())
                {
                    s.push(b.top());
                    b.pop();
                    b.push(a[i]);
                }
                else
                s.push(a[i]);
            }
            while(u[cur]==i)//GET命令
            {
                ii++;
                while(b.size()!=ii)//维护个数为i
                {
                    int tmp=s.top();
                    s.pop();
                    b.push(tmp);
                }
                printf("%d\n",b.top());
                cur++;
            }
        }
        if(t)
        printf("\n");
    }
    return 0;
}

题解 UVA501 【Black Box】

标签:大于   href   set   使用   efi   can   amp   black   ace   

原文地址:https://www.cnblogs.com/lhm-/p/12229806.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!