AcWing 839:模拟堆 ← multiset + unordered_map

【题目来源】
https://www.acwing.com/problem/content/841/

【题目描述】
维护一个集合,初始时集合为空,支持如下几种操作:

  1. I x,插入一个数 x;
  2. PM,输出当前集合中的最小值;
  3. DM,删除当前集合中的最小值(数据保证此时的最小值唯一);
  4. D k,删除第 k 个插入的数;
  5. C k x,修改第 k 个插入的数,将其变为 x;
    现在要进行 N 次操作,对于所有第 2 个操作,输出当前集合的最小值。

【输入格式】
第一行包含整数 N。
接下来 N 行,每行包含一个操作指令,操作指令为 I x,PM,DM,D k 或 C k x 中的一种。

【输出格式】
对于每个输出指令 PM,输出一个结果,表示当前集合中的最小值。
每个结果占一行。

【数据范围】
1≤N≤10^5
−10^9≤x≤10^9
数据保证合法。

【输入样例】
8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM

【输出样例】
-10
6

【算法分析】
● 堆是一棵完全二叉树。
● unordered_map:https://blog.csdn.net/hnjzsyjyj/article/details/131628676
● multiset:https://cplusplus.com/reference/set/multiset/
● 本题的数组模拟实现参见:https://blog.csdn.net/hnjzsyjyj/article/details/146358448

【算法代码】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

multiset<int> h; //heap
unordered_map<int,int> a;
int n,k,x,tot;
string op;

int main() {
    cin>>n;
    while(n--) {
        cin>>op;
        if(op=="I") cin>>x, h.insert(x), a[++tot]=x;
        else if(op=="PM") cout<<*h.begin()<<endl;
        else if(op=="DM") h.erase(h.begin());
        else if(op=="D") cin>>k, h.erase(h.find(a[k]));
        else cin>>k>>x, h.erase(h.find(a[k])), h.insert(a[k]=x);
    }
}

/*
in:
8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM

out:
-10
6
*/

【参考文献】
https://www.acwing.com/solution/content/156923/
https://www.cnblogs.com/ddja/p/15898586.html
https://www.acwing.com/solution/content/6100/
https://www.acwing.com/solution/content/5541/
https://www.cnblogs.com/Hayasaka/p/14294147.html

相关推荐
橘颂TA4 天前
【C++】树和二叉树的实现(上)
数据结构·算法·二叉树·
azaz_plus5 天前
C++ priority_queue 堆
开发语言·c++·stl··priority_queue
DARLING Zero two♡23 天前
【初阶数据结构】森林里的树影 “堆” 光:堆
c语言·数据结构·c++··
Ronin-Lotus1 个月前
程序代码篇---C/C++中的变量存储位置
c语言·c++···静态区·文字常量区·变量存储位置
Lostgreen2 个月前
堆(Heap)的原理与C++实现
数据结构·堆排序·
轩情吖2 个月前
二叉树-堆(补充)
c语言·数据结构·c++·后端·二叉树··排序
keysky2 个月前
「SPOJ2666」QTREE4 - Query on a tree IV
线段树··树链剖分
Tisfy3 个月前
LeetCode 1705.吃苹果的最大数目:贪心(优先队列) - 清晰题解
算法·leetcode·优先队列·贪心·
跳跳的向阳花3 个月前
16-02、JVM系列之:内存与垃圾回收篇(二)
jvm·内存··老年代·方法区·新生代