洛谷P1801 黑匣子

Posted H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1801 黑匣子相关的知识,希望对你有一定的参考价值。

  题目传送门

  分析:这题和另外一个题目中位数非常相似,有兴趣可以先看看,比这一题简单。首先暴力模拟还是别想了,估计30%的数据都有点悬。正解应该是用二叉堆。但是如果用一个堆当然不方便,所以建两个堆,一个大根堆,一个小根堆,每次只要出现询问操作,就把小根堆的堆顶丢进大根堆中维护,然后输出就可以了,但是要注意,操作过程中一定要让大根堆的堆顶小于小根队的堆顶,也就是保证大根堆中的元素就是题目中的前i小的元素。这样题目就变的非常容易了。

  Code:

技术分享图片
//It is made by HolseLee on 18th Mar 2018
//Luogu.org P1801
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
const int N=2e5+7;
int n,m,opt[N],a[N];
int hmax[N],hmin[N];
int sizex,sizen;
inline int read()
{
  char ch=getchar();int num=0;bool flag=false;
  while(ch<0||ch>9){if(ch==-)flag=true;ch=getchar();}
  while(ch>=0&&ch<=9){num=num*10+ch-0;ch=getchar();}
  return flag?-num:num;
}
inline void insert_min(int x)
{
  hmin[++sizen]=x;
  int ka=sizen;
  while(ka>1){
    if(hmin[ka]<hmin[ka/2]){
      swap(hmin[ka],hmin[ka/2]);
      ka/=2;}
    else break;
  }
}
inline void insert_max(int x)
{
  hmax[++sizex]=x;
  int ka=sizex;
  while(ka>1){
    if(hmax[ka]>hmax[ka/2]){
      swap(hmax[ka],hmax[ka/2]);
      ka/=2;}
    else break;
  }
}
inline void delet_min()
{
  hmin[1]=hmin[sizen--];
  int ka=1,s=ka*2;
  while(s<=sizen){
    if(s<sizen&&hmin[s+1]<hmin[s])
      s++;
    if(hmin[s]<hmin[ka]){
      swap(hmin[s],hmin[ka]);
      ka=s;s=ka*2;}
    else break;
  }
}
inline void delet_max()
{
  hmax[1]=hmax[sizex--];
  int ka=1,s=ka*2;
  while(s<=sizex){
    if(s<sizex&&hmax[s+1]>hmax[s])
      s++;
    if(hmax[s]>hmax[ka]){
      swap(hmax[s],hmax[ka]);
      ka=s;s=ka*2;}
    else break;
  }
}
inline int change()
{
  int ka=hmin[1];
  delet_min();
  insert_max(ka);
  return ka;
}
int main()
{
  bool flag=false;
  n=read();m=read();
  for(int i=1;i<=n;i++)
    a[i]=read();
  for(int i=1;i<=m;i++){
    int x=read();opt[x]++;}
  for(int i=1;i<=n;i++){
    insert_min(a[i]);
    if(flag&&hmin[1]<hmax[1]){
      int minn=hmin[1];
      int maxx=hmax[1];
      delet_min();insert_min(maxx);
      delet_max();insert_max(minn);
    }
    while(opt[i]>0){
      flag=true;opt[i]--;
      int ans=change();
      printf("%d\n",ans);
    }
  }
  return 0;
}
View Code

 

 

以上是关于洛谷P1801 黑匣子的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1801 黑匣子

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

落谷P1801 黑匣子

P1801 黑匣子[堆]

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

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