POJ 3481 Double Queue SBT || treap

1 篇文章 0 订阅

题目:

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

题意:

有一组操作,有如下三种:

  1. 0,结束操作
  2. 1 k p,把一个客户k加入到队列中,优先级为p
  3. 2, 把队列中优先级最高的客户取出来
  4. 3, 把队列中优先级最低的客户取出来

SBTree treap 写的
SBTree:

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

using namespace std;

const int N = 100000 + 10, INF = 0x3f3f3f3f;

struct node
{
    int val, sz, son[2];
    int id;
    void init(int _val, int _sz, int _id)
    {
        val = _val, sz = _sz, id = _id;
        son[0] = son[1] = 0;
    }
};
struct SBTree
{
    int tot, root;
    node tr[N];
    void init()
    {
        tot = 0, root = 0;
        tr[0].init(0, 0, 0);
    }
    void update(int x)
    {
        tr[x].sz = tr[tr[x].son[0]].sz + tr[tr[x].son[1]].sz + 1;
    }
    void rotate(int &x, int p)
    {
        int y = tr[x].son[!p];
        tr[x].son[!p] = tr[y].son[p];
        tr[y].son[p] = x;
        update(x), update(y);
        x = y;
    }
    void maintain(int &x, int p)
    {
        if(tr[tr[tr[x].son[p]].son[p]].sz > tr[tr[x].son[!p]].sz)
            rotate(x, !p);
        else if(tr[tr[tr[x].son[p]].son[!p]].sz > tr[tr[x].son[!p]].sz)
            rotate(tr[x].son[p], p), rotate(x, !p);
        else return;

        maintain(tr[x].son[0], 0);
        maintain(tr[x].son[1], 1);
        maintain(x, 0);
        maintain(x, 1);
    }
    void insert(int &x, int val, int id)
    {
        if(x == 0) tr[x = ++tot].init(val, 1, id);
        else
        {
            tr[x].sz++;
            int p = val > tr[x].val;
            insert(tr[x].son[p], val, id);
            maintain(x, p);
        }
    }
//用此删除函数时,待删除的节点可以不存在
//    bool del_node(int &x, int val)
//    {
//        if(x == 0) return false;
//        if(tr[x].val == val)
//        {
//            if(tr[x].son[0] && tr[x].son[1])
//            {
//                int y = get_pre(x);
//                tr[x].val = tr[y].val;
//                tr[x].sz--;
//                return del_node(tr[x].son[0], tr[x].val);
//            }
//            else
//            {
//                x = tr[x].son[0] + tr[x].son[1];
//                return true;
//            }
//        }
//        else
//        {
//            int p = val > tr[x].val;
//            if(del_node(tr[x].son[p], val))
//            {
//                tr[x].sz--; return true;
//            }
//            else return false;
//        }
//    }
    void del_node(int &x, int val)
    {
        if(tr[x].val == val)
        {
            if(tr[x].son[0] && tr[x].son[1])
            {
                int y = get_pre(x);
                tr[x].val = tr[y].val;
                tr[x].sz--;
                del_node(tr[x].son[0], tr[x].val);
            }
            else x = tr[x].son[0] + tr[x].son[1];
        }
        else
        {
            tr[x].sz--;
            int p = val > tr[x].val;
            del_node(tr[x].son[p], val);
        }
    }
    int get_pre(int x) //返回前驱的下标
    {
        int y = tr[x].son[0];
        while(tr[y].son[1]) y = tr[y].son[1];
        return y;
    }
    int get_sub(int x) //返回后继的下标
    {
        int y = tr[x].son[1];
        while(tr[y].son[0]) y = tr[y].son[0];
        return y;
    }
    int get_kth(int x, int k) //得到第k小值
    {
        if(k == tr[tr[x].son[0]].sz + 1) return tr[x].val;
        else if(k > tr[tr[x].son[0]].sz + 1) return get_kth(tr[x].son[1], k - tr[tr[x].son[0]].sz - 1);
        else return get_kth(tr[x].son[0], k);
    }
    int get_rank(int x, int val) //得到val从小到大的排名
    {
        if(val == tr[x].val) return tr[tr[x].son[0]].sz + 1;
        else if(val > tr[x].val) return get_rank(tr[x].son[1], val) + tr[tr[x].son[0]].sz + 1;
        else return get_rank(tr[x].son[0], val);
    }
    int get_max_min(int x, int p)//得到最大值或者最小值
    {
        while(tr[x].son[p]) x = tr[x].son[p];
        return x;
    }
}sbt;
int main()
{
    int op, k, p;
    sbt.init();
    while(scanf("%d", &op), op)
    {
        if(op == 1)
        {
            scanf("%d%d", &k, &p);
            sbt.insert(sbt.root, p, k);
        }
        else if(op == 2)
        {
            int x = sbt.get_max_min(sbt.root, 1);
            printf("%d\n", sbt.tr[x].id);
            sbt.del_node(sbt.root, sbt.tr[x].val);
        }
        else
        {
            int x = sbt.get_max_min(sbt.root, 0);
            printf("%d\n", sbt.tr[x].id);
            sbt.del_node(sbt.root, sbt.tr[x].val);
        }
    }
    return 0;
}

treap:

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

using namespace std;

const int N = 100000 + 10;

struct node
{
    int val, pri, son[2];
    int id;
    void init(int _val, int _id, int _pri)
    {
        val = _val, id = _id, pri = pri;
        son[0] = son[1] = 0;
    }
};
struct Treap
{
    int tot, root;
    node tr[N];
    void init()
    {
        tot = 0, root = 0;
        tr[0].init(0, 0, 0);
    }
    void rotate(int &x, int p)
    {
        int y = tr[x].son[!p];
        tr[x].son[!p] = tr[y].son[p];
        tr[y].son[p] = x;
        x = y;
    }
    void insert(int &x, int val, int id)
    {
        if(x == 0) tr[x = ++tot].init(val, id, rand());
        else
        {
            int p = val > tr[x].val;
            insert(tr[x].son[p], val, id);
            if(tr[x].pri < tr[tr[x].son[p]].pri) rotate(x, !p);
        }
    }
    void del_node(int &x, int val)
    {
        if(tr[x].val == val)
        {
            if(tr[x].son[0] && tr[x].son[1])
            {
                int p = tr[tr[x].son[0]].pri > tr[tr[x].son[1]].pri;
                rotate(x, p);
                del_node(tr[x].son[p], val);
            }
            else
            {
                if(tr[x].son[0] != 0) x = tr[x].son[0];
                else x = tr[x].son[1];
            }
        }
        else
        {
            int p = val > tr[x].val;
            del_node(tr[x].son[p], val);
        }
    }
    int get(int x, int p)
    {
        while(tr[x].son[p]) x = tr[x].son[p];
        return x;
    }
}treap;
int main()
{
    int op, id, val;
    treap.init();
    while(scanf("%d", &op), op)
    {
        if(op == 1)
        {
            scanf("%d%d", &id, &val);
            treap.insert(treap.root, val, id);
        }
        else if(op == 2)
        {
            int x = treap.get(treap.root, 1);
            printf("%d\n", treap.tr[x].id);
            treap.del_node(treap.root, treap.tr[x].val);
        }
        else if(op == 3)
        {
            int x = treap.get(treap.root, 0);
            printf("%d\n", treap.tr[x].id);
            treap.del_node(treap.root, treap.tr[x].val);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值