好吧,这道题目感觉就是一道裸题了,要求插入删除,查询最大最小,直接动手写喽。
Tips:模板是long long的,这里用不着long long我也懒得改。
这其实是一个双端优先队列。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
ll cnt=1,rt;
struct Node{
ll son[2],pri,val,sz,k;
void set_size();
void newnode(ll v,ll ke){son[0]=son[1]=0;sz=1,pri=rand(),val=v,k=ke;}
}tree[100010];
void Node::set_size(){
sz=1+tree[son[0]].sz+tree[son[1]].sz;
}
void rot(bool p,ll &x){
ll k=tree[x].son[!p];
tree[x].son[!p]=tree[k].son[p];
tree[k].son[p]=x;
tree[x].set_size();
tree[k].set_size();
x=k;
}
void ins(ll key,ll &x,ll k){
if(x){
bool p=key>=tree[x].val;
ins(key,tree[x].son[p],k);
if(tree[tree[x].son[p]].pri>tree[x].pri)
rot(!p,x);
}
else
tree[x=cnt++].newnode(key,k);
tree[x].set_size();
}
void del(ll key,ll &x){
if(key==tree[x].val){
if(!tree[x].son[0])
x=tree[x].son[1];
else if(!tree[x].son[1])
x=tree[x].son[0];
else{
bool p=tree[tree[x].son[0]].pri>tree[tree[x].son[1]].pri;
rot(p,x);
del(key,tree[x].son[p]);
}
}
else
del(key,tree[x].son[key>=tree[x].val]);
if(x)
tree[x].set_size();
}
ll find_num(ll key,ll &x){
if(!x)
return 0;
if(tree[x].val>key)
return find_num(key,tree[x].son[0]);
else
return tree[tree[x].son[0]].sz+1+find_num(key,tree[x].son[1]);
}
ll find_rank(ll level,ll &x){
if(level==tree[tree[x].son[0]].sz+1)
return x;
else if(level>tree[tree[x].son[0]].sz+1)
return find_rank(level-tree[tree[x].son[0]].sz-1,tree[x].son[1]);
else
return find_rank(level,tree[x].son[0]);
}
ll find_min(ll x){
if(!x)
return 0;
while(tree[x].son[0])
x=tree[x].son[0];
ll ans=tree[x].k;
del(tree[x].val,rt);
return ans;
}
ll find_max(ll x){
if(!x)
return 0;
while(tree[x].son[1])
x=tree[x].son[1];
ll ans=tree[x].k;
del(tree[x].val,rt);
return ans;
}
int order,k,p;
int main(){
while(scanf("%d",&order)&&order){
if(order==1){
scanf("%d%d",&k,&p);
ins(p,rt,k);
}
else if(order==2)
printf("%d\n",find_max(rt));
else
printf("%d\n",find_min(rt));
}
return 0;
}