1、B站视频链接:A15 堆 堆排序_哔哩哔哩_bilibili
题目链接:【模板】堆 - 洛谷
#include <bits/stdc++.h>
using namespace std;
int a[1000010],cnt;
void up(int u){//上浮
if(u/2&&a[u/2]>a[u]){
swap(a[u],a[u/2]),up(u/2);
}
}
void down(int u){//下沉
int v=u;//用v临时存下根节点
if(u*2<=cnt&&a[u*2]<a[v])v=u*2;
if(u*2+1<=cnt&&a[u*2+1]<a[v])v=u*2+1;
if(u!=v)swap(a[u],a[v]),down(v);
}
void push(int x){//插入
a[++cnt]=x;
up(cnt);
}
void pop(){//删除
a[1]=a[cnt--];//用堆的尾部代替堆的顶部,并将个数减一
down(1);//顶部下沉
}
int main(){
int n;scanf("%d",&n);
while(n--){
int op,x;scanf("%d",&op);
if(op==1)scanf("%d",&x),push(x);
else if(op==2)printf("%d\n",a[1]);
else pop();
}
return 0;
}
STL代码
#include <bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int>>q;
int main(){
int n;
scanf("%d",&n);
while(n--){
int op,x;
scanf("%d",&op);
if(op==1)scanf("%d",&x),q.push(x);
else if(op==2)printf("%d\n",q.top());
else q.pop();
}
return 0;
}
2、B站视频链接:A16 对顶堆 第k大的数_哔哩哔哩_bilibili
#include <bits/stdc++.h>
using namespace std;
priority_queue<int> a;//大根堆
priority_queue<int,vector<int>,greater<int>>b;//小根堆
int main(){
int n,w;
scanf("%d%d",&n,&w);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if(b.empty()||x>=b.top())b.push(x);//插入小根堆
else a.push(x);//插入大根堆
int k=max(1,i*w/100);//第k大
while(b.size()>k)a.push(b.top()),b.pop();//调整
while(b.size()<k)b.push(a.top()),a.pop();
printf("%d ",b.top());//取值
}
return 0;
}
练习题目:RMID2 - Running Median Again - 洛谷
#include <bits/stdc++.h>
using namespace std;
priority_queue<int> a;//大根堆
priority_queue<int,vector<int>,greater<int>>b;//小根堆
int main(){
int t,x; scanf("%d",&t); //t组数据
while(t--){
while(scanf("%d",&x)&&x){
if(x>0){
if(b.empty()||x>=b.top()) b.push(x); //插入
else a.push(x);
int k=(b.size()+a.size())/2+1; //第k大数
while(b.size()>k) a.push(b.top()), b.pop(); //调整
while(b.size()<k) b.push(a.top()), a.pop();
}
else printf("%d\n",b.top()), b.pop(); //取值,删除
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
priority_queue<int> a;//大根堆
priority_queue<int,vector<int>,greater<int>>b;//小根堆
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if(b.empty()||x>=b.top())b.push(x);
else a.push(x);
int k=(i+1)/2;
while(b.size()>k)a.push(b.top()),b.pop();
while(b.size()<k)b.push(a.top()),a.pop();
if(i%2)printf("%d\n",b.top());//奇数取值
}
return 0;
}