题目有三个操作,插入一个优先级为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; }