hiho刷题日记——第二十八天题外话·堆

题目

小Ho有一个糖果盒子,每过一段时间小Ho都会将新买来的糖果放进去,同时他也会不断的从其中挑选出最大的糖果出来吃掉,但是寻找最大的糖果不是一件非常简单的事情,所以小Ho希望能够用计算机来他帮忙计算这个问题!
对于100%的数据,满足1<=N<=10^5, 1<=w<=10^5。

思路

用数组构建一个完全树。
1
2 3
4 5 6 7
并保证所有的父亲节点都比子节点大。形成一个大根堆。
7
5 6
4 2 3 1

添加

加到数组尾部,下标i。
并与其父亲节点(下标i/2)比较大小互换。
重复上面操作直到比父亲节点小。

输出

答案是直接就是根节点(下标1)
将最后一个节点(下标i)放到根节点。
然后将其根据大根堆的规则向下移动。

代码

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=100000+1;
int N;
int w[MAXN],top=1;

void add(int c)
{
  int i=top++;
  while(i!=1 && w[i>>1]<c)
  {
    w[i]=w[i>>1];
    i>>=1;
  }
  w[i]=c;
}

int out()
{
  int ans=w[1];
  int i=1;

  w[1]=w[--top];
  while((i=i<<1)<top)
  {
    if(w[i]>w[i|1])
    {
      if(w[i>>1]<w[i])
      {
        w[i>>1]=w[i];
        w[i]=w[top];
      }
    }
    else
    {
      i|=1;
      if(w[i>>1]<w[i])
      {
        w[i>>1]=w[i];
        w[i]=w[top];
      }
    }
  }
  return ans;
}

int main()
{
  scanf("%d",&N);
  char o; int c;
  while(N--)
  {
    scanf("%c%c",&o,&o);
    if(o=='A')
    {
      scanf("%d",&c);
      add(c);
    }
    else printf("%d\n",out());
  }
  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值