• Treap板子


    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int SIZE = 1e5 + 5;
    
    class Treap {
        struct Node {
            int l, r;
            int val, dat; //节点的关键码,权值
            int cnt, size; //副本数,子树大小
        }a[SIZE];
    
    public:
        int tot, root, INF = 0x7fffffff;
    
        Treap() {
            tot = 0;
            New(-INF), New(INF);
            root = 1, a[1].r = 2;
            Update(root);
        }
    
        int New(int val) {
            a[++tot].val = val;
            a[tot].r = a[tot].l = 0;
            a[tot].dat = rand();
            a[tot].cnt = a[tot].size = 1;
            return tot; 
        }
    
        void Update(int p) {
            a[p].size = a[a[p].l].size + a[a[p].r].size + a[p].cnt;
        }
    
        int GetRankByVal(int p, int val) {
            if (p == 0) return 0;
            
            if (val == a[p].val) return a[a[p].l].size + 1;
            if (val < a[p].val) return GetRankByVal(a[p].l, val);
            return GetRankByVal(a[p].r, val) + a[a[p].l].size + a[p].cnt;
        }
    
        int GetValByRank(int p, int rank) {
            if (p == 0) return INF;
    
            if (a[a[p].l].size >= rank) return GetValByRank(a[p].l, rank);
            if (a[a[p].l].size + a[p].cnt >= rank) return a[p].val;
            return GetValByRank(a[p].r, rank - a[a[p].l].size - a[p].cnt);
        }
    
        void zig(int &p) { //右旋
            int q = a[p].l;
            a[p].l = a[q].r, a[q].r = p, p = q;
            Update(a[p].r), Update(p);
        }
    
        void zag(int &p) { //左旋
            int q = a[p].r;
            a[p].r = a[q].l, a[q].l = p, p = q; 
            Update(a[p].l), Update(p);
        }
    
        void Insert(int &p, int val) {
            if (p == 0) {
                p = New(val);
                return;
            }
    
            if (val == a[p].val) {
                ++a[p].cnt, Update(p);
                return;
            }
    
            if (val < a[p].val) {
                Insert(a[p].l, val);
                if (a[p].dat < a[a[p].l].dat) zig(p);
            } else {
                Insert(a[p].r, val);
                if (a[p].dat < a[a[p].r].dat) zag(p);
            } 
    
            Update(p);
        }
    
        int GetPre(int val) {
            int ans = 1; // INF
            int p = root;
    
            while (p) {
                if(val == a[p].val) {
                    if (a[p].l > 0) {
                        p = a[p].l;
                        while (a[p].r > 0) p = a[p].r;
                        ans = p;
                    }
                    break;
                } 
    
                if (a[p].val < val && a[p].val > a[ans].val) ans = p;
    
                p = a[p].val > val ? a[p].l : a[p].r;
            }
    
            return a[ans].val;
        }
    
        int GetNext(int val) {
            int ans = 2; //-INF
            int p = root;
    
            while (p) {
                if (a[p].val == val) {
                    if (a[p].r > 0) {
                        p = a[p].r;
                        while (a[p].l > 0) p = a[p].l;
                        ans = p;
                    }
                    break;
                }
    
                if (a[p].val > val && a[p].val < a[ans].val) ans = p;
                
                p = a[p].val > val ? a[p].l : a[p].r;
            }
    
            return a[ans].val;
        }
    
        void Remove(int &p, int val) {
            if (p == 0) return;
    
            if (val == a[p].val) {
                if (a[p].cnt > 1) {
                    --a[p].cnt, Update(p);
                    return;
                }
    
                if (a[p].l || a[p].r) {
                    if (a[p].r == 0 || a[a[p].l].dat > a[a[p].r].dat)
                        zig(p), Remove(a[p].r, val);
                    else zag(p), Remove(a[p].l, val);
                    
                    Update(p);
                } 
                else p = 0;
                return;
            }
    
            val < a[p].val ? Remove(a[p].l, val) : Remove(a[p].r, val);
            Update(p);
        }
    };
    
    int n, _;
    
    int main() {
        ios::sync_with_stdio(0); cin.tie(nullptr);
    
        Treap t = Treap();
        for (cin >> _; _; --_) {
            int opt, x; cin >> opt >> x;
    
            switch (opt)
            {
            case 1:
                t.Insert(t.root, x);
                break;
            case 2:
                t.Remove(t.root, x);
                break;
            case 3:
                cout << t.GetRankByVal(t.root, x) - 1 << endl;
                break;
            case 4:
                cout << t.GetValByRank(t.root, x + 1) << endl;
                break;
            case 5:
                cout << t.GetPre(x) << endl;
                break;
            case 6:
                cout << t.GetNext(x) << endl;
                break;
            default:
                break;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    nova-conductor与AMQP(二)
    nova-conductor与AMQP(一)
    nova-api中ExtensionManager的构造
    openstack身份认证与API请求流程
    nova-api源码分析(APP中用到的开源库)
    nova-api源码分析(WSGI server的创建及启动)
    novaclient源码分析
    机器学习-----线性回归浅谈(Linear Regression)
    分布式文件系统--GFS
    java 小结2 多态问题和容器介绍
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13162372.html
Copyright © 2020-2023  润新知