#include <iostream>
#include <cstring>
using namespace std;
template<typename T=int>
inline T read(){
T X=0; bool flag=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<1)+(X<<3)+ch-'0',ch=getchar();
if(flag) return X;
return ~(X-1);
}
template<typename T=int>
inline void write(T X){
if(X<0) putchar('-'),X=~(X-1);
T s[20],top=0;
while(X) s[++top]=X%10,X/=10;
if(!top) s[++top]=0;
while(top) putchar(s[top--]+'0');
putchar('\n');
}
const int N=1e6+5;
int n;
template<class T=int>
class Heap{
public:
// 构造函数和析构函数貌似没什么问题QwQ
Heap(bool (*_cmp)(T,T)=[](T a,T b)->bool{return a<b;},T n=1e6):
a(new T[n+5]),top(0),cmp(_cmp){memset(a,0,sizeof(a));}
~Heap(){delete[] a;}
void build(T *_a,int n){ // 用一个数组建堆,这题没用到
memcpy(a+1,_a,sizeof(int)*n);
top=n;
for(int i=n>>1; i; i--)
sink(i);
}
void ins(T x){ // 插入
a[++top]=x; // 尾部插入,然后上浮
swim(top);
}
void del(){
swap(a[1],a[top--]); // 删除最值,将最后一个节点放到 a[1],然后下沉
sink(1);
}
T find(){return a[1];}
private:
T *a,top;
bool (*cmp)(T,T); // 奇怪的 "函数指针",和 sort 传的 cmp 一个用
void swim(T x){ // 将某个节点上浮
for(int i=x; i>1 && cmp(a[i],a[i>>1]); i>>=1)
swap(a[i],a[i>>1]);
}
void sink(T x){ // 将某个节点下沉
for(int i=x,t=son(i); t<=top && cmp(a[t],a[i]); i=t,t=son(i))
swap(a[i],a[t]);
}
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;} // 左儿子和右儿子
// son 用于下沉时选择一个较小的儿子
inline int son(int x){return ls(n)+(rs(n)<=top && cmp(a[rs(n)],a[ls(n)]));}
};
Heap h;
int main(){
n=read();
while(n--){
switch(read()){
case 1: h.ins(read()); break;
case 2: write(h.find()); break;
case 3: h.del(); break;
default: break;
}
}
return 0;
}
刚把第一组数据下下来一个一个手输(很小的数据),发现最后几个删除的时候寄了QwQ下面是数据
输入
15
1 5384
2
3
1 4337
1 291
3
1 3776
2
1 2490
1 3903
1 5038
1 4504
3
3
3
输出
5384
3776