链接:C++中的堆和栈
这篇博客是讲堆的几种定义
题目
洛谷 P3817 中位数
洛谷 P1168 中位数
P1168代码
STL版本
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n,a1;
priority_queue<int,vector<int> ,greater<int> >minheap;//小根堆
priority_queue<int>maxheap;//大根堆
inline int read(){
int x=0,w=1;char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
int main() {
n=read();a1=read();
printf("%d\n",a1);
minheap.push(a1);
for(int i=1; i<=(n-1)/2; i++) {
int a,b;
a=read();b=read();
if(a<minheap.top()) { maxheap.push(a);} else { minheap.push(a);}
if(b<minheap.top()) { maxheap.push(b);} else { minheap.push(b);}
while(maxheap.size()>=minheap.size()) { minheap.push(maxheap.top()); maxheap.pop();}
while(maxheap.size()<minheap.size()-1) {maxheap.push(minheap.top());minheap.pop();}
printf("%d\n",minheap.top());
}
return 0;
}
手动模拟堆(不过有点长)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define fp(i,a,b) for(register int i=a;i<=b;++i)
using namespace std;
int n,t1,t2,size1,size2,mid;
int big[400005],small[400005];
//首先,想想为什么可以用
inline int read(){
int x=0,w=1;char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
inline void big_put(int x){
big[++size2]=x;
int now=size2,next;
while(now>1){
next=now>>1;
if(big[now]<=big[next]) return;
swap(big[now],big[next]);
now=next;
}
}
inline int big_get(){
int now=1,next,v=big[1];
big[1]=big[size2--];
while(now<<1<=size2){
next=now<<1;
if(next<size2&&big[next+1]>big[next]) ++next;
if(big[now]>=big[next]) break;
swap(big[next],big[now]);
now=next;
}
return v;
}
inline void small_put(int x){
small[++size1]=x;
int now=size1,next;
while(now>1){
next=now>>1;
if(small[now]>=small[next]) return;
swap(small[now],small[next]);
now=next;
}
}
inline int small_get(){
int now=1,next,v=small[1];
small[1]=small[size1--];
while(now<<1<=size1){
next=now<<1;
if(next<size1&&small[next+1]<small[next]) ++next;
if(small[now]<=small[next]) break;
swap(small[next],small[now]);
now=next;
}
return v;
}
int main(){
n=read();t1=read();
big_put(t1);printf("%d\n",mid=t1);
for(register int i=1;i<<1<n;++i){
t1=read();t2=read();
if(t1>mid) small_put(t1);else big_put(t1);
if(t2>mid) small_put(t2);else big_put(t2);
if(size1>=size2) big_put(small_get());
if(size1+1<size2) small_put(big_get());
printf("%d\n",mid=big[1]);
}
return 0;
}
P3387代码
STL版本
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,mid;
char s[10];
priority_queue<int,vector<int> ,greater<int> >minheap;//小根堆
priority_queue<int>maxheap;//大根堆
inline int read(){
int x=0,w=1;char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
int main() {
n=read();
for(register int i=1; i<=n; ++i) {
int a;
a=read();
if(a>mid) { minheap.push(a);} else { maxheap.push(a);}
while(minheap.size()>=maxheap.size()) { maxheap.push(minheap.top()); minheap.pop();}
while(minheap.size()+1<maxheap.size()) {minheap.push(maxheap.top());maxheap.pop();}
}
m=read();
for(register int i=1;i<=m;++i){
int a;
cin>>s;
if(s[0]=='a'){
a=read();
if(a>mid) { minheap.push(a);} else { maxheap.push(a);}
while(minheap.size()>=maxheap.size()) { maxheap.push(minheap.top()); minheap.pop();}
while(minheap.size()+1<maxheap.size()) {minheap.push(maxheap.top());maxheap.pop();}
}
else printf("%d\n",mid=maxheap.top());
}
return 0;
}
手动模拟版本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define fp(i,a,b) for(register int i=a;i<=b;++i)
using namespace std;
int n,t1,t2,size1,size2,mid,m;
int big[400005],small[400005];
char s[10];
inline int read(){
int x=0,w=1;char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
inline void big_put(int x){
big[++size2]=x;
int now=size2,next;
while(now>1){
next=now>>1;
if(big[now]<=big[next]) return;
swap(big[now],big[next]);
now=next;
}
}
inline int big_get(){
int now=1,next,v=big[1];
big[1]=big[size2--];
while(now<<1<=size2){
next=now<<1;
if(next<size2&&big[next+1]>big[next]) ++next;
if(big[now]>=big[next]) break;
swap(big[next],big[now]);
now=next;
}
return v;
}
inline void small_put(int x){
small[++size1]=x;
int now=size1,next;
while(now>1){
next=now>>1;
if(small[now]>=small[next]) return;
swap(small[now],small[next]);
now=next;
}
}
inline int small_get(){
int now=1,next,v=small[1];
small[1]=small[size1--];
while(now<<1<=size1){
next=now<<1;
if(next<size1&&small[next+1]<small[next]) ++next;
if(small[now]<=small[next]) break;
swap(small[next],small[now]);
now=next;
}
return v;
}
int main(){
n=read();
for(register int i=1;i<=n;++i){
t1=read();
if(t1>mid) small_put(t1);else big_put(t1);
if(size1>=size2) big_put(small_get());
if(size1+1<size2) small_put(big_get());
}
m=read();
for(register int i=1;i<=m;++i){
cin>>s;
if(s[0]=='a') {
t1=read();
if(t1>mid) small_put(t1);else big_put(t1);
if(size1>=size2) big_put(small_get());
if(size1+1<size2) small_put(big_get());
}
if(s[0]=='m') printf("%d\n",mid=big[1]);
}
return 0;
}