首页 > 其他分享 >模拟堆

模拟堆

时间:2023-01-24 13:33:24浏览次数:46  
标签:read ll len swap ph 模拟 define

简介

比较模拟堆和 STL 的优先队列

a a a
a a a
a a a

模拟堆和 STL 的优先队列 priority_queue 相同之处在于它们都可以维护极值

实现

模板题1(AcWing.838

题目描述

输入一个长度为 \(n\) 的整数数列,从小到大输出前 \(m\) 小的数。

样例

in:

5 3
4 5 1 3 2

out:

1 2 3

简单堆实现

#include <bits/stdc++.h>
#define ll long long
#define rll register ll
#define cll const ll
#define N 100005
using namespace std;
inline ll read()
{
    rll x=0;bool f=1;static char c=getchar();
    while(!isdigit(c)){if(c=='-') f=0;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return (f==1)?x:-x;
}
inline void write(ll x)
{
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+48);
}
cll n=read();
ll m=read(),len=n,a[N];
inline void down(ll u)
{
    ll t=u;
    if((u<<1)<=len&&a[u<<1]<a[t]) t=u<<1;
    if((u<<1|1)<=len&&a[u<<1|1]<a[t]) t=u<<1|1;
    if(u!=t) swap(a[u],a[t]),down(t);
}
inline void up(ll u)
{
    while((u>>1)&&a[u>>1]>a[u])
    {
        swap(a[u>>1],a[u]);
        u>>=1;
    }
}
int main()
{
    for(rll i=1;i<=n;i++) a[i]=read();
    for(rll i=(n>>1);i;i--) down(i);
    while(m--)
    {
        write(a[1]),putchar(' ');
        a[1]=a[len--],down(1);
    }
    return 0;
}

模板题2(AcWing.839

题目描述

维护一个集合,初始时集合为空,支持如下几种操作:

  1. I x ,插入一个数 \(x\)
  2. PM ,输出当前集合中的最小值
  3. DM ,删除当前集合中的最小值(数据保证此时的最小值唯一)
  4. D k ,删除第 \(k\) 个插入的数
  5. C k x ,修改第 \(k\) 个插入的数,将其变为 \(x\)

现在要进行 \(n\) 次操作,对于所有第 2 个操作,输出当前集合的最小值。

样例

in:

8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM

out:

-10
6

复杂堆实现

#include <bits/stdc++.h>
#define ll long long
#define rll register ll
#define cll const ll
#define N 100005
using namespace std;
inline ll read()
{
    rll x=0;bool f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-') f=0;c=getchar();}
    while(c>=48&&c<=57){x=x*10+(c^48);c=getchar();}
    return f?x:-x;
}
inline void write(ll x)
{
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+48);
}
ll n=read(),m,len,a[N],ph[N],hp[N];
inline void heap_swap(ll x,ll y)
{
    swap(ph[hp[x]],ph[hp[y]]);
    swap(hp[x],hp[y]);
    swap(a[x],a[y]);
}
inline void down(ll u)
{
    ll t=u;
    if((u<<1)<=len&&a[u<<1]<a[t]) t=u<<1;
    if((u<<1|1)<=len&&a[u<<1|1]<a[t]) t=u<<1|1;
    if(u!=t) heap_swap(u,t),down(t);
}
inline void up(ll u)
{
    while((u>>1)&&a[u>>1]>a[u])
    {
        heap_swap(u>>1,u);
        up(u>>1);
    }
}
int main()
{
    while(n--)
    {
        string op;cin >> op;
        if(op=="I")
        {
            cll x=read();
            a[++len]=x;
            ph[++m]=len,hp[len]=m;
            up(len);
        }
        else if(op=="PM") write(a[1]),putchar('\n');
        else if(op=="DM") heap_swap(1,len--),down(1);
        else if(op=="D")
        {
            cll k=read(),x=ph[k];
            heap_swap(x,len--);
            up(x),down(x);
        }
        else if(op=="C")
        {
            cll k=read(),x=read();
            a[ph[k]]=x;
            down(ph[k]),up(ph[k]);
        }
    }
    return 0;
}

标签:read,ll,len,swap,ph,模拟,define
From: https://www.cnblogs.com/wangxuzhou-blog/p/17066026.html

相关文章

  • 记录一次python爬虫模拟登录吧
    测试网站是本人学校,费话不多说下面开始首先直接导库,过程中需要时间戳,rsa加密importrequestsimportreimporttimefromCrypto.PublicKeyimportRSAfromCrypto.Ci......
  • 模拟退火算法
    eg1:LeecodeclassSolution{public:intmaxHappyGroups(intbatchSize,vector<int>&groups){w=groups;n=w.size();m=batchS......
  • 用Python写一个模拟过年礼花的程序
    介绍过年了,好不容易熬到疫情放开,也该放烟花放鞭炮庆祝下了,祝大家新年快乐,身体健康,万事如意,希望新的一年诸邪退散,春暖花开~主程序importpygame,math,time,random,......
  • m基于GA遗传优化+SA模拟退火的混合改进算法的多产品多机器生产优化matlab仿真
    1.算法描述       这里,我们首先介绍一下改进算法的基本原理,按照前面说的,这里我们主要将GA和SA进行合并。        这里,我研究了下,将两种算法做如下方法的......
  • m基于GA遗传优化+SA模拟退火的混合改进算法的多产品多机器生产优化matlab仿真
    1.算法描述这里,我们首先介绍一下改进算法的基本原理,按照前面说的,这里我们主要将GA和SA进行合并。这里,我研究了下,将两种算法做如下方法的结合:首先,在之前做的改进GA......
  • T-SQL 模拟彩票预测
    比较简单,只是模拟彩票出数字的过程,不计算单一数字的出现概率。传统上来说,每次彩票出号的概率都是独立事件,单纯的在可选数字内随机实现即可。本文探索的是实现简单的预测......
  • Android Studio模拟器无法上网问题的解决
    问题AndroidStudio模拟器中app可以正常使用网络,但是内嵌的H5无法连接网络。使用AndroidStudio开发时经常使用其自带的模拟器进行app模拟和仿真,并且可以使用模拟器创建a......
  • P1014 [NOIP1999 普及组] Cantor 表(模拟/枚举)
    https://www.luogu.com.cn/problem/P1014详解见代码内部注释部分#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<LL,LL>PII;cons......
  • Java模拟用户登录
    publicstaticvoidmain(String[]args){//1.告诉了已知的用户名和密码Stringname="zhangan";Stringpassword="12345";Scannersc=newScanner(......
  • 「解题报告」NOIP2021模拟19 乘法
    题目描述求\(n!\)的十六进制下去尾零后的后十六位。多组测试数据。数据范围\(T\le10,n<2^{64}\)这题目太简洁了,awsl思路开始裂开十六进制下的十六位就是\(......