• Treap


    (Treap) 是平衡树的一种,(Treap)(Tree)(Heap) 的组合

    核心思想

    每个节点有两个属性 (key)(val) 其中的 key 满足 BST 二叉搜索树的性质,其中序遍历是一个有序序列。val 满足 Heap 堆的性质,一个节点的 (val) 值大于其孩子节点的 (val)

    随机分配 (val) 使得 期望的 (BST) 是平均深度的

    结构定义

    struct Node{
        int l, r;
        int key, val;//key是BST关键字, val是Heap关键字
        int cnt, size;
    }tr[N];
    
    int root, idx;
    

    节点分配

    int get_node(int key){
        tr[ ++ idx].key = key;
        tr[idx].val = rand(); //随机数据
        tr[idx].cnt = tr[idx].size = 1;
        return idx;
    }
    

    插入操作

    void insert(int &p, int key)
    {
        if (!p) p = get_node(key);
        else if (tr[p].key == key) tr[p].cnt ++ ;
        else if (tr[p].key > key)
        {
            insert(tr[p].l, key);
            if (tr[tr[p].l].val > tr[p].val) zig(p);//右旋
        }
        else
        {
            insert(tr[p].r, key);
            if (tr[tr[p].r].val > tr[p].val) zag(p);//左旋
        }
        pushup(p);
    }
    

    删除操作

    void remove(int &p, int key)
    {
        if (!p) return;
        if (tr[p].key == key)
        {
            if (tr[p].cnt > 1) tr[p].cnt -- ;
            else if (tr[p].l || tr[p].r)
            {
                if (!tr[p].r || tr[tr[p].l].val > tr[tr[p].r].val)
                {
                    zig(p);
                    remove(tr[p].r, key);
                }
                else
                {
                    zag(p);
                    remove(tr[p].l, key);
                }
            }
            else p = 0;
        }
        else if (tr[p].key > key) remove(tr[p].l, key);
        else remove(tr[p].r, key);
    
        pushup(p);
    }
    

    旋转操作

    void zig(int &p)    // 右旋
    {
        int q = tr[p].l;
        tr[p].l = tr[q].r, tr[q].r = p, p = q;
        pushup(tr[p].r), pushup(p);
    }
    
    void zag(int &p)    // 左旋
    {
        int q = tr[p].r;
        tr[p].r = tr[q].l, tr[q].l = p, p = q;
        pushup(tr[p].l), pushup(p);
    }
    

    模板

    普通平衡树

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 100010, INF = 1e8;
    
    int n;
    struct Node
    {
        int l, r;
        int key, val;//key是BST关键字, val是Heap关键字
        int cnt, size;
    }tr[N];
    
    int root, idx;
    
    void pushup(int p)
    {
        tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + tr[p].cnt;
    }
    
    int get_node(int key)
    {
        tr[ ++ idx].key = key;
        tr[idx].val = rand(); //随机数据
        tr[idx].cnt = tr[idx].size = 1;
        return idx;
    }
    
    void zig(int &p)    // 右旋
    {
        int q = tr[p].l;
        tr[p].l = tr[q].r, tr[q].r = p, p = q;
        pushup(tr[p].r), pushup(p);
    }
    
    void zag(int &p)    // 左旋
    {
        int q = tr[p].r;
        tr[p].r = tr[q].l, tr[q].l = p, p = q;
        pushup(tr[p].l), pushup(p);
    }
    
    void build()
    {
        get_node(-INF), get_node(INF);
        root = 1, tr[1].r = 2;
        pushup(root);
        if (tr[1].val < tr[2].val) zag(root);
    }
    
    
    void insert(int &p, int key)
    {
        if (!p) p = get_node(key);
        else if (tr[p].key == key) tr[p].cnt ++ ;
        else if (tr[p].key > key)
        {
            insert(tr[p].l, key);
            if (tr[tr[p].l].val > tr[p].val) zig(p);
        }
        else
        {
            insert(tr[p].r, key);
            if (tr[tr[p].r].val > tr[p].val) zag(p);
        }
        pushup(p);
    }
    
    void remove(int &p, int key)
    {
        if (!p) return;
        if (tr[p].key == key)
        {
            if (tr[p].cnt > 1) tr[p].cnt -- ;
            else if (tr[p].l || tr[p].r)
            {
                if (!tr[p].r || tr[tr[p].l].val > tr[tr[p].r].val)
                {
                    zig(p);
                    remove(tr[p].r, key);
                }
                else
                {
                    zag(p);
                    remove(tr[p].l, key);
                }
            }
            else p = 0;
        }
        else if (tr[p].key > key) remove(tr[p].l, key);
        else remove(tr[p].r, key);
    
        pushup(p);
    }
    
    int get_rank_by_key(int p, int key)    // 通过数值找排名
    {
        if (!p) return 0;   // 本题中不会发生此情况
        if (tr[p].key == key) return tr[tr[p].l].size + 1;
        if (tr[p].key > key) return get_rank_by_key(tr[p].l, key);
        return tr[tr[p].l].size + tr[p].cnt + get_rank_by_key(tr[p].r, key);
    }
    
    int get_key_by_rank(int p, int rank)   // 通过排名找数值
    {
        if (!p) return INF;     // 本题中不会发生此情况
        if (tr[tr[p].l].size >= rank) return get_key_by_rank(tr[p].l, rank);
        if (tr[tr[p].l].size + tr[p].cnt >= rank) return tr[p].key;
        return get_key_by_rank(tr[p].r, rank - tr[tr[p].l].size - tr[p].cnt);
    }
    
    int get_prev(int p, int key)   // 找到严格小于key的最大数
    {
        if (!p) return -INF;
        if (tr[p].key >= key) return get_prev(tr[p].l, key);
        return max(tr[p].key, get_prev(tr[p].r, key));
    }
    
    int get_next(int p, int key)    // 找到严格大于key的最小数
    {
        if (!p) return INF;
        if (tr[p].key <= key) return get_next(tr[p].r, key);
        return min(tr[p].key, get_next(tr[p].l, key));
    }
    
    int main()
    {
        build();
    
        scanf("%d", &n);
        while (n -- )
        {
            int opt, x;
            scanf("%d%d", &opt, &x);
            if (opt == 1) insert(root, x);
            else if (opt == 2) remove(root, x);
            else if (opt == 3) printf("%d
    ", get_rank_by_key(root, x) - 1);
            else if (opt == 4) printf("%d
    ", get_key_by_rank(root, x + 1));
            else if (opt == 5) printf("%d
    ", get_prev(root, x));
            else printf("%d
    ", get_next(root, x));
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    百度地图API地理位置和坐标转换
    WebClient 通过get和post请求api
    C#模拟POST提交表单(二)--HttpWebRequest以及HttpWebResponse
    C#模拟POST提交表单(一)--WebClient
    百度外卖接口调试 C#版
    DWZ(JUI) 教程 跨域请求 iframeNavTab
    订餐系统之同步美团商家订单
    订餐系统之同步饿了么商家订单
    外卖订单爬虫(美团,饿了么,百度外卖)
    订餐系统之获取淘宝外卖订单
  • 原文地址:https://www.cnblogs.com/sduwh/p/13958538.html
Copyright © 2020-2023  润新知