题意:
。。。
思路:
这道题用来作SBT的练习了。。。
// SBT节点,固定域 l, r, sz
// 需要一个key来比较大小
struct node {
int l, r, sz, val, K;
node (int x=0, int y=0):l(0), r(0), sz(0), val(x), K(y){}
};
struct SBT {
node a[Maxn+5]; // a[0] 是空节点,与所有外部节点相连
int root, tot;
void init() {root = tot = 0;}
inline void rot_R(int &x) { // 右旋
int k = a[x].l;
a[x].l = a[k].r;
a[k].r = x;
a[k].sz += a[x].sz;
a[x].sz = a[a[x].l].sz + a[a[x].r].sz + 1;
x = k;
}
inline void rot_L(int &x) { // 左旋
int k = a[x].r;
a[x].r = a[k].l;
a[k].l = x;
a[k].sz += a[x].sz;
a[x].sz = a[a[x].l].sz + a[a[x].r].sz + 1;
x = k;
}
void maintain(int &x, int flag) {
int L = a[x].l, R = a[x].r;
if (!flag) { // 左子树和右子树的子树比较
if (a[a[L].l].sz > a[R].sz) {
rot_R(x);
}
else if (a[a[L].r].sz > a[R].sz) {
rot_L(a[x].l);
rot_R(x);
}
else return;
}
else { // 右子树和左子树的子树比较
if (a[a[R].r].sz > a[L].sz) {
rot_L(x);
}
else if (a[a[R].l].sz > a[L].sz) {
rot_R(a[x].r);
rot_L(x);
}
else return;
}
maintain(a[x].l, 0);
maintain(a[x].r, 1);
maintain(x, 0);
maintain(x, 1);
}
node remove(int &x, int key) { // 用前驱覆盖
node del;
--a[x].sz;
if (key == a[x].val || (key < a[x].val && !a[x].l) || (key > a[x].val && !a[x].r)) {
del = a[x];
if (!a[x].l || !a[x].r) // 如果是外部节点,直接用子节点覆盖
x = a[x].l + a[x].r;
else { // 否则使用前驱覆盖
node tmp = remove(a[x].l, a[x].val + 1);
a[x].val = tmp.val;a[x].K = tmp.K;
}
}
else if (key < a[x].val)
del = remove(a[x].l, key);
else
del = remove(a[x].r, key);
return del;
}
void insert(int &x, int val, int K) {
if (x == 0) {
x = ++tot;
a[x] = node(val, K);
a[x].sz = 1;
return;
}
++a[x].sz;
if (val < a[x].val) {
insert(a[x].l, val, K);
}
else {
insert(a[x].r, val, K);
}
maintain(x, val >= a[x].val);
//cout << "after maintain mid: ";sbt_mid_order(x);cout << endl;
//cout << "after maintain pre: ";sbt_pre_order(x);cout << endl;
}
node front() {
int i;
for (i=root;a[i].l;i=a[i].l);
return a[i];
}
node back() {
int i;
for (i=root;a[i].r;i=a[i].r);
return a[i];
}
void sbt_mid_order(int x) {
if (!x) return;
sbt_mid_order(a[x].l);
cout << a[x].val << ' ';
sbt_mid_order(a[x].r);
}
void sbt_pre_order(int x) {
if (!x) return;
cout << a[x].val << ' ';
sbt_pre_order(a[x].l);
sbt_pre_order(a[x].r);
}
};
SBT sbt;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
sbt.init();
int code, k, p;
while (cin >> code && code) {
if (code == 1) {
cin >> k >> p;
// cout << "\ninsert: " << p << endl;
sbt.insert(sbt.root, p, k);
}
else if (code == 2) {
node tmp = sbt.back();
if (tmp.K)
sbt.remove(sbt.root, tmp.val);
cout << tmp.K << endl;
}
else if (code == 3) {
node tmp = sbt.front();
if (tmp.K)
sbt.remove(sbt.root, tmp.val);
cout << tmp.K << endl;
}
//cout << "mid: ";sbt.sbt_mid_order(sbt.root);cout << endl;
//cout << "pre: ";sbt.sbt_pre_order(sbt.root);cout << endl;
//cout << "size: " << sbt.a[sbt.root].sz << endl;
}
return 0;
}