題目有三個操作,插入一個優先級爲p的,名字爲k的人;取出優先級最小的人,輸出名字; 取出優先級最大的人,輸出名字。
可以再sbt的域中加一個值存儲名字,也可以直接map搞定....................這裏只用了insert,getmin,getmax,remove或者del操作。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <climits>//形如INT_MAX一類的
#define MAX 111111
#define INF 0x7FFFFFFF
#define REP(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define L(x) x<<1
#define R(x) x<<1|1
# define eps 1e-5
//#pragma comment(linker, "/STACK:36777216") ///傳說中的外掛
using namespace std;
struct sbt {
int l,r,s,key;
} tr[MAX];
int top , root;
void left_rot(int &x) {
int y = tr[x].r;
tr[x].r = tr[y].l;
tr[y].l = x;
tr[y].s = tr[x].s; //轉上去的節點數量爲先前此處節點的size
tr[x].s = tr[tr[x].l].s + tr[tr[x].r].s + 1;
x = y;
}
void right_rot(int &x) {
int y = tr[x].l;
tr[x].l = tr[y].r;
tr[y].r = x;
tr[y].s = tr[x].s;
tr[x].s = tr[tr[x].l].s + tr[tr[x].r].s + 1;
x = y;
}
void maintain(int &x,bool flag) {
if(flag == 0) { //左邊
if(tr[tr[tr[x].l].l].s > tr[tr[x].r].s) {//左孩子左子樹size大於右孩子size
right_rot(x);
} else if(tr[tr[tr[x].l].r].s > tr[tr[x].r].s) {//左孩子右子樹size大於右孩子size
left_rot(tr[x].l);
right_rot(x);
} else return ;
} else { //右邊
if(tr[tr[tr[x].r].r].s > tr[tr[x].l].s) { //右孩子的右子樹大於左孩子
left_rot(x);
} else if(tr[tr[tr[x].r].l].s > tr[tr[x].l].s) { //右孩子的左子樹大於左孩子
right_rot(tr[x].r);
left_rot(x);
} else return ;
}
maintain(tr[x].l,0);
maintain(tr[x].r,1);
}
void insert(int &x,int key) {
if(x == 0) { //空節點
x = ++ top;
tr[x].l = tr[x].r = 0;
tr[x].s = 1;
tr[x].key = key;
} else {
tr[x].s ++;
if(key < tr[x].key) insert(tr[x].l,key);
else insert(tr[x].r,key);
maintain(x,key >= tr[x].key);
}
}
int del(int &p,int w) {
if (tr[p].key==w || (tr[p].l == 0 && w < tr[p].key) || (tr[p].r == 0 && w > tr[p].key)) {
int delnum = tr[p].key;
if (tr[p].l == 0 || tr[p].r == 0) p = tr[p].l + tr[p].r;
else tr[p].key=del(tr[p].l,INF);
return delnum;
}
if (w < tr[p].key) return del(tr[p].l,w);
else return del(tr[p].r,w);
}
int remove(int &x,int key) {
int k;
tr[x].s --;
if(key == tr[x].key || (key < tr[x].key && tr[x].l == 0) || (key > tr[x].key && tr[x].r == 0)) {
k = tr[x].key;
if(tr[x].l && tr[x].r) {
tr[x].key = remove(tr[x].l,tr[x].key + 1);
} else {
x = tr[x].l + tr[x].r;
}
} else if(key > tr[x].key) {
k = remove(tr[x].r,key);
} else if(key < tr[x].key) {
k = remove(tr[x].l,key);
}
return k;
}
int getmin() { //二叉搜索樹找最小值
int x;
for(x = root; tr[x].l; x = tr[x].l) ;
return tr[x].key;
}
int getmax() {
int x;
for(x = root ; tr[x].r; x = tr[x].r) ;
return tr[x].key;
}
int pred(int &x,int y,int key)
//前驅 小於
{
if(x == 0) return y;
if(tr[x].key < key)//加上等號,就是小於等於
return pred(tr[x].r,x,key);
else return pred(tr[x].l,y,key);
}//pred(root,0,key)
int succ(int &x,int y,int key) { //後繼 大於
if(x == 0) return y;
if(tr[x].key > key)
return succ(tr[x].l,x,key);
else return succ(tr[x].r,y,key);
}
int select(int &x,int k) { //求第k小數
int r = tr[tr[x].l].s + 1;
if(r == k) return tr[x].key;
else if(r < k) return select(tr[x].r,k - r);
else return select(tr[x].l,k);
}
int rank(int &x,int key) { //求第K小數的逆運算
if(key < tr[x].key) return rank(tr[x].l,key);
else if(key > tr[x].key) return rank(tr[x].r,key);
else return tr[tr[x].l].s + 1;
}
void inorder(int &x) {
if(x == 0) return;
else {
inorder(tr[x].l);
cout<< x <<" "<< tr[x].key << " " <<tr[x].s << " " <<tr[tr[x].l].key << " " << tr[tr[x].r].key << endl;
inorder(tr[x].r);
}
}
map<int ,int>mm;
int main() {
root = top = 0;
int a,key,p;
while(scanf("%d",&a) && a) {
if(a == 1) {
scanf("%d%d",&key,&p);
mm[p] = key;
insert(root,p);
} else if(a == 2) {
int maxx = getmax();
printf("%d\n",mm[maxx]);
del(root,maxx);
} else {
int minn = getmin();
printf("%d\n",mm[minn]);
del(root,minn);
}
}
return 0;
}