zoukankan      html  css  js  c++  java
  • PBDS学习笔记(一)

    PBDS学习笔记(一)

    pbds简介

    平板电视库学习笔记。总结一份偏向acm应用的pbds库笔记。
    
    //首先需要以下头文件以及命名空间
    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    
    using namespace __gnu_pbds;
    

    hash

    简介

        cc_hash_table<int, bool> h1; //拉链法处理冲突
        gp_hash_table<int, bool> h2; //探测法处理冲突
    

    例题:n个数,m次询问,查询数字是否出现,用法类似map

    codevs 1230

    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <bits/stdc++.h>
    
    using namespace __gnu_pbds;
    using namespace std;
    
    int main()
    {
        cc_hash_table<int, bool> h1; //拉链法处理冲突
        gp_hash_table<int, bool> h2; //探测法处理冲突
        int n, m;
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= n; i++ ) {
            int x;
            scanf("%d", &x);
            h1[x] = 1;
        }
        while(m--) {
            int x;
            scanf("%d", &x);
            printf("%s
    ", h1[x] ? "YES" : "NO");
        }
        return 0;
    }
    
    

    平常用的堆是 c++stl 中的 priority_queue. pbds支持可并堆。

    首先需要头文件

    #include <ext/pb_ds/priority_queue.hpp>
    

    例题1:FJUTOJ 2109 优先队列的实现(代替priority_queue的一些功能)

    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/priority_queue.hpp>
    #include <bits/stdc++.h>
    
    using namespace __gnu_pbds;
    using namespace std;
    
    int data, n;
    
    char opt[10];
    
    int main()
    {
        __gnu_pbds::priority_queue<int, less<int>, pairing_heap_tag> que;
        while(~scanf("%d ", &n)) {
            que.clear();
            while(!que.empty()) {
                que.pop();
            }
            for(int i = 1; i <= n; i ++ ) {
                scanf("%s", opt);
                if(opt[1] == 'u') {
                    scanf("%d", &data);
                    que.push(data);
                } else {
                    if(que.empty()) {
                        puts("Empty");
                    } else {
                        printf("%d
    ", que.top());
                        que.pop();
                    }
                }
            }
        }
        return 0;
    }
    

    堆的合并

    咕咕咕~~~,代补,今天主要想学平衡树部分。
    

    红黑树

    简介

    听说可以实现名次树和自定义函数。偷懒的时候代替splay,比赛不能用还能拿来对拍
    
    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <bits/stdc++.h>
    
    using namespace __gnu_pbds;
    using namespace std;
    typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
    
    /// int类型
    /// null_type为映射类型, 低版本g++为 null_mapped_type
    /// less<int>, greater<int> 比较器
    /// rb_tree_tag 和 splay_tree_tag 选择树的类型
    /// tree_order_statistics_node_update 结点更新
    
    /// insert, erase
    /// order_of_key rank
    /// find_by_order() kth
    /// lower_bound() 前继, >=x 最小的迭代器
    /// upper_bound() 后继   >x  最小的迭代器
    /// a.join(b) b并入a,前提是两颗树的取值范围不相交
    /// a.split(v, b) key <= v的属于a,其他属于
    /// 注意,插入的元素会去重,如set
    

    实现一道例题 FJUTOJ 不差钱

    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <bits/stdc++.h>
    
    using namespace __gnu_pbds;
    using namespace std;
    
    const int MAXN = 3000000 + 10;
    
    int price, menu[MAXN], cnt[MAXN];
    
    typedef tree<int, null_type, greater<int>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
    
    int n, opt, x;
    
    rbtree tre;
    
    int main()
    {
        scanf("%d", &price);
        int id = 1;
        while(~scanf("%d", &opt) && opt) {
            scanf("%d", &x);
            if(opt == 1) { /// add price of x
                tre.insert(x);
                cnt[x]++;       /// 价格x的菜的数量
                menu[id++] = x; /// 第id道菜价格x
                continue;
            }
            if(opt == 2) {
                int p = menu[x];
                if(cnt[p]) {
                    cnt[p]--;
                }
                continue;
            }
            if(opt == 3) {
                int res = *tre.find_by_order(x - 1);
                if(res > price) {
                    puts("Dui bu qi,Mei you.");
                } else if(cnt[res] == 0) {
                    puts("Mei you. Zhe ge ke yi you. Zhe ge zhen mei you!");
                } else {
                    printf("You. %d Yuan.
    ", res);
                }
            }
        }
        return 0;
    }
    

    顺便付上正常的splay的解法,有点长,平板电视真好用

    #include <ext/pb_ds/tree_policy.hpp>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <bits/stdc++.h>
    
    using namespace __gnu_pbds;
    using namespace std;
    
    const int MAXN = 1000000 + 10;
    
    int price, menu[MAXN], cnt[MAXN];
    
    template<class T>
    inline bool nextInt(T &n) {
        T x = 0, tmp = 1; char c = getchar();
        while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
        if(c == EOF) return false;
        if(c == '-') c = getchar(), tmp = -1;
        while(c >= '0' && c <= '9') x *= 10, x += (c - '0'), c = getchar();
        n = x*tmp; return true;
    }
    
    template<class T>
    inline void Out(T n) {
        if(n < 0) { putchar('-'); n = -n; }
        int len = 0, data[20];
        while(n) { data[len++] = n%10; n /= 10; }
        if(!len) data[len++] = 0;
        while(len--) putchar(data[len]+48);
    }
    
    
    struct Splay_Tree {
    
        struct Node {
            int father, childs[2], key, cnt, _size;
            inline void init() {
                father = childs[0] = childs[1] = key = cnt = _size = 0;
            }
            inline void init(int father, int lchild, int rchild, int key, int cnt, int sz) {
                this -> father = father, childs[0] = lchild, childs[1] = rchild;
                this -> key = key, this -> cnt = cnt, _size = sz;
            }
        } tre[MAXN];
    
        int sign, root;
    
        inline void init() {
            sign = root = 0;
        }
    
        inline bool judge(int x) {
            return tre[ tre[x].father ].childs[1] == x;
        }
    
        inline void update(int x) {
            if(x) {
                tre[x]._size = tre[x].cnt;
                if(tre[x].childs[0]) {
                    tre[x]._size += tre[ tre[x].childs[0] ]._size;
                }
                if(tre[x].childs[1]) {
                    tre[x]._size += tre[ tre[x].childs[1] ]._size;
                }
            }
        }
    
        inline void rotate(int x) {
            int y = tre[x].father, z = tre[y].father, k = judge(x);
    
            //tre[y].childs[k] = tre[x].childs[!k], tre[ tre[x].childs[!k] ].father = y;
            //tre[x].childs[!k] = y, tre[y].father = x;
            //tre[z].childs[ tre[z].childs[1] == y ] = x, tre[x].father = z;
    
            if(k == 0) { ///zig
                tre[y].childs[0] = tre[x].childs[1], tre[ tre[x].childs[1] ].father = y;
                tre[x].childs[1] = y, tre[y].father = x;
            } else { ///zag
                tre[y].childs[1] = tre[x].childs[0], tre[ tre[x].childs[0] ].father = y;
                tre[x].childs[0] = y, tre[y].father = x;
            }
            tre[z].childs[ tre[z].childs[1] == y ] = x, tre[x].father = z;
    
            update(y);
        }
    
        inline void splay(int x,int goal) {
            for(int father; (father = tre[x].father) != goal; rotate(x) ) {
                if(tre[father].father != goal) {
                    rotate(judge(x) == judge(father) ? father : x);
                }
            }
            root = x;
        }
    
        inline void insert_node(int x) {
            if(root == 0) {
                tre[++sign].init(0, 0, 0, x, 1, 1);
                root = sign;
                return ;
            }
            int now = root, father = 0;
            while(1) {
                if(tre[now].key == x) {
                    tre[now].cnt ++;
                    update(now), update(father);
                    splay(now, 0);
                    break;
                }
                father = now;
                if(x > tre[now].key) {
                    now = tre[now].childs[1];
                } else {
                    now = tre[now].childs[0];
                }
                if(now == 0) {
                    tre[++sign].init(father, 0, 0, x, 1, 1);
                    if(x > tre[father].key) {
                        tre[father].childs[1] = sign;
                    } else {
                        tre[father].childs[0] = sign;
                    }
                    update(father);
                    splay(sign, 0);
                    break;
                }
            }
        }
    
        inline int pre() {
            int now = tre[root].childs[0];
            while(tre[now].childs[1]) {
                now = tre[now].childs[1];
            }
            return now;
        }
    
        inline int next() {
            int now = tre[root].childs[1];
            while(tre[now].childs[0]) {
                now = tre[now].childs[0];
            }
            return now;
        }
    
        inline int find_rank(int x) { /// 找x的排名
            int now = root, ans = 0;
            while(1) {
                if(x < tre[now].key) {
                    now = tre[now].childs[0];
                }
                else {
                    if(tre[now].childs[0]) {
                        ans += tre[ tre[now].childs[0] ]._size;
                    }
                    if(x == tre[now].key) {
                        splay(now, 0);
                        return ans + 1;
                    }
                    ans += tre[now].cnt;
                    now = tre[now].childs[1];
                }
            }
        }
    
        inline int find_by_order(int x) {
            int now = root;
            while(1) {
                if(tre[now].childs[1] && x <= tre[ tre[now].childs[1] ]._size ) {
                    now = tre[now].childs[1];
                } else {
                    int rchild = tre[now].childs[1], sum = tre[now].cnt;
                    if(rchild) {
                        sum += tre[rchild]._size;
                    }
                    if(x <= sum) {
                        int ans = tre[now].key;
                        splay(now, 0);
                        return ans;
                    }
                    x -= sum;
                    now = tre[now].childs[0];
                }
            }
        }
    
        inline int find_rankx(int x) { /// 找排名为x的数字
            int now = root;
            while(1) {
                if(tre[now].childs[0] && x <= tre[ tre[now].childs[0] ]._size ) {
                    now = tre[now].childs[0];
                } else {
                    int lchild = tre[now].childs[0], sum = tre[now].cnt;
                    if(lchild) {
                        sum += tre[lchild]._size;
                    }
                    if(x <= sum) {
                        return tre[now].key;
                    }
                    x -= sum;
                    now = tre[now].childs[1];
                }
            }
        }
    
        inline void del(int x) {
            find_rank(x);
            if(tre[root].cnt > 1) {
                tre[root].cnt --;
                update(root);
                return ;
            }
            if(!tre[root].childs[0] && !tre[root].childs[1]) {
                tre[root].init();
                root = 0;
                return ;
            }
            if(!tre[root].childs[0]) {
                int old_root = root;
                root = tre[root].childs[1], tre[root].father = 0, tre[old_root].init();
                return ;
            }
            if(!tre[root].childs[1]) {
                int old_root = root;
                root = tre[root].childs[0], tre[root].father = 0, tre[old_root].init();
                return ;
            }
            int pre_node = pre(), old_root = root;
            splay(pre_node, 0);
            tre[root].childs[1] = tre[old_root].childs[1];
            tre[ tre[old_root].childs[1] ].father = root;
            tre[old_root].init();
            update(root);
        }
    
        inline bool find(int x) {
            int now = root;
            while(1) {
                if(now == 0) {
                    return 0;
                }
                if(x == tre[now].key) {
                    splay(now, 0);
                    return 1;
                }
                if(x > tre[now].key) {
                    now = tre[now].childs[1];
                } else {
                    now = tre[now].childs[0];
                }
            }
        }
    
    } tre;
    
    int n, opt, x;
    
    int main()
    {
        scanf("%d", &price);
        int id = 1;
        while(nextInt(opt) && opt) {
            //scanf("%d", &x);
            nextInt(x);
            if(opt == 1) { /// add price of x
                tre.insert_node(x);
                cnt[x]++;       /// 价格x的菜的数量
                menu[id++] = x; /// 第id道菜价格x
                continue;
            }
            if(opt == 2) {
                int p = menu[x];
                tre.find(p);
                if(cnt[p]) {
                    cnt[p]--;
                }
                continue;
            }
            if(opt == 3) {
                int res = tre.find_by_order(x);
                if(res > price) {
                    puts("Dui bu qi,Mei you.");
                } else if(cnt[res] == 0) {
                    puts("Mei you. Zhe ge ke yi you. Zhe ge zhen mei you!");
                } else {
                    printf("You. %d Yuan.
    ", res);
                }
            }
        }
    
    
        return 0;
    }
    
    
  • 相关阅读:
    媒体格式分析之flv -- 基于FFMPEG
    x264源代码分析-转
    比特币的相关问题整理(详细的)
    比特币价格首超黄金 年涨幅超7600%
    比特币不是虚拟货币,这是一个真实世界----李笑来
    比特币投机者嘲笑称比特币为泡沫的人原因
    比特币:一个让投资人为之疯狂的神奇货币
    比特币沉浮录
    比特币淘金热席卷中国专业“挖矿机”受疯抢
    国内首起比特币交易平台诈骗案涉案人被捕
  • 原文地址:https://www.cnblogs.com/Q1143316492/p/9536364.html
Copyright © 2011-2022 走看看