POJ 3481 Double Queue【SBT】

http://poj.org/problem?id=3481

该SBT模板只实现了一些简单的操作,我会不断完善其它功能。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

const int maxn = 100010;

struct Node {
    int key, val;
    Node(){};
    Node(int a, int b) {
        key = a; val = b;
    }
    bool operator < (Node b) {
        return val < b.val;
    }
    bool operator > (Node b) {
        return val > b.val;
    }
    bool operator == (Node b) {
        return val == b.val;
    }
    bool operator >= (Node b) {
        return val >= b.val;
    }
    Node operator + (int a) {
        return Node(key, val + a);
    }
};

template<typename Type>
class SBT
{
public:
    SBT() { Clear(); }
	void Clear() {
        tot = 0, root = 0;
        lch[0] = rch[0] = sz[0] = 0;
    }
    int Size() { return sz[root]; }
    bool Empty() { return 0 == sz[root]; }
    bool Find(Type k) { return Find(root, k); }
    void InsertR(Type k) { Insert(root, k); }
    void Insert(Type k) { if (!Find(k)) InsertR(k); }
    void Delete(Type k) { Delete(root, k); }
    int GetRank(Type k) { return GetRank(root, k); }
    Type GetKth(int k) { return GetKth(root, k); }
    Type GetMin() { return GetKth(root, 1); }
    Type GetMax() { return GetKth(root, Size()); }
    
private:
    void LeftRotate(int &t) {
        int k = rch[t];
        rch[t] = lch[k];
        lch[k] = t;
        sz[k] = sz[t];
        sz[t] = 1 + sz[lch[t]] + sz[rch[t]];
        t = k;
    }
    void RightRotate(int &t) {
        int k = lch[t];
        lch[t] = rch[k];
        rch[k] = t;
        sz[k] = sz[t];
        sz[t] = 1 + sz[lch[t]] + sz[rch[t]];
        t = k;
    }
    void Maintain(int &t, bool flag) {
        if (0 == t) return ;
        if (false == flag) {
            if (sz[lch[lch[t]]] > sz[rch[t]]) {
                RightRotate(t);
            } else if (sz[rch[lch[t]]] > sz[rch[t]]) {
                LeftRotate(lch[t]);
                RightRotate(t);
            } else {
                return ;
            }
        } else {
            if (sz[rch[rch[t]]] > sz[lch[t]]) {
                LeftRotate(t);
            } else if (sz[lch[rch[t]]] > sz[lch[t]]) {
                RightRotate(rch[t]);
                LeftRotate(t);
            } else {
                return ;
            }
        }
        Maintain(lch[t], false);
        Maintain(rch[t], true);
        Maintain(t, false);
        Maintain(t, true);
    }
    Type GetKth(int t, int k) {
        if (sz[lch[t]] >= k) 
            return GetKth(lch[t], k);
        if (sz[lch[t]] == k - 1) 
            return key[t];
        return GetKth(rch[t], k - sz[lch[t]] - 1);
    }
    int GetRank(int t, Type k) {
        if (0 == t) return 1; // 查找不存在的元素的rank,可以得到小于该元素的元素的个数 
        if (k < key[t]) return GetRank(lch[t], k);
        if (k > key[t]) return sz[lch[t]] + 1 + GetRank(rch[t], k);
        return sz[lch[t]] + 1;
    }
    bool Find(int t, Type k) {
        if (0 == t) {
            return false;
        } else if (k < key[t]) {
            return Find(lch[t], k);
        } else {
            return (key[t] == k || Find(rch[t], k));
        }
    }
    void Insert(int &t, Type k) {
        if (t == 0) {
            t = ++tot;
            lch[t] = rch[t] = 0;
            sz[t]= 1;
            key[t] = k;
            return ;
        }
        sz[t]++;
        if (k < key[t]) {
            Insert(lch[t], k);
        } else {
            Insert(rch[t], k);
        }
        Maintain(t, k >= key[t]);
    }
    Type Delete(int &t, Type k) {
        sz[t]--;
        if ((key[t] == k) || (k < key[t] && lch[t] == 0) || (k > key[t] && rch[t] == 0)) {
            Type tmp = key[t];
            if (0 == lch[t] || 0 == rch[t]) {
                t = lch[t] + rch[t];
            } else {
                key[t] = Delete(lch[t], key[t] + 1);
            }
            return tmp;
        } else {
            if (k < key[t]) {
                return Delete(lch[t], k);
            } else {
                return Delete(rch[t], k);
            }
        }
    }
    
private:
    int sz[maxn];
	Type key[maxn];
	int lch[maxn];
	int rch[maxn];
	int root, tot;
};

SBT<Node> sbt;

int main()
{
    int op, a, b;
    sbt.Clear();
    while (scanf("%d", &op)) {
        if (0 == op) break;
        if (1 == op) {
            scanf("%d%d", &a, &b);
            sbt.Insert(Node(a, b));
        } else if (2 == op) {
            if (sbt.Empty()) {
                printf("0\n");
            } else {
                Node tmp = sbt.GetMax();
                printf("%d\n", tmp.key);
                sbt.Delete(tmp);
            }
        } else {
            if (sbt.Empty()) {
                printf("0\n");
            } else {
                Node tmp = sbt.GetMin();
                printf("%d\n", tmp.key);
                sbt.Delete(tmp);
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值