前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >对顶堆求区间k小(大)数

对顶堆求区间k小(大)数

作者头像
glm233
发布2020-09-28 10:30:03
7130
发布2020-09-28 10:30:03
举报
文章被收录于专栏:glm的全栈学习之路

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

首先,这道题让我们求每次的第i大值,而i是会移动的——那我们就可以理解为,我们需要知道第i大值和第i+1大值(请撕烤)。那用什么数据结构呢?

  • 首先,要确定第i大值,就可以知道i-1~1是从大到小的;
  • 相似的,i+1~n的元素是从小到大的。
  • 可以用堆来完成

我们用一个大根堆来保存前i-1大数,大根堆确定了其中的元素是从大到小的;再用一个小根堆来存剩下的数,小根堆堆顶就是第i大数。

代码语言:javascript
复制
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    char ch=getchar();int s=0,w=1;
    while(ch<48||ch>57){if(ch=='-')w=-1;ch=getchar();}
    while(ch>=48&&ch<=57){s=s*10+ch-48;ch=getchar();}
    return s*w;
}
inline void write(int x)
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+48);
}
int m,n;
int a[200005],b[200005];
priority_queue<int>maxx;
priority_queue<int,vector<int>,greater<int> >minn;
int main()
{
m=read(),n=read();
for(register int i=1;i<=m;i++)
{
    a[i]=read();
}
for( register  int i=1;i<=n;i++)
{
    b[i]=read();
}
int l=1,r;
for( register int i=1;i<=n;i++)
{
    r=b[i];
    for(register int j=l;j<=r;j++)
    {
        maxx.push(a[j]);
        if(maxx.size()>=i)
        {
            minn.push(maxx.top());
            maxx.pop();
        }
    }
    l=r+1;
    cout<<minn.top()<<endl;
    maxx.push(minn.top());
    minn.pop();
}
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/06/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • P1801 黑匣子_NOI导刊2010提高(06)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档