1. 程式人生 > >poj 3481 Double Queue(平衡二叉樹基礎練習題)

poj 3481 Double Queue(平衡二叉樹基礎練習題)

題意:
。。。
思路:
這道題用來作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; }