• set实现常见平衡树操作


    参考习题:LuoGu3369

    【模板】普通平衡树

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入 $x$ 数 2. 删除 $x$ 数(若有多个相同的数,因只删除一个) 3. 查询 $x$ 数的排名(排名定义为比当前数小的数的个数 $+1$ ) 4. 查询排名为 $x$ 的数 5. 求 $x$ 的前驱(前驱定义为小于 $x$,且最大的数) 6. 求 $x$ 的后继(后继定义为大于 $x$,且最小的数)

    输入输出格式

    输入格式

    第一行为 $n$,表示操作的个数,下面 $n$ 行每行有两个数 $ ext{opt}$ 和 $x$,$ ext{opt}$ 表示操作的序号( $ 1 leq ext{opt} leq 6 $ )

    输出格式

    对于操作 $3,4,5,6$ 每行输出一个数,表示对应答案

    输入输出样例

    输入样例 #1

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    输出样例 #1

    106465
    84185
    492737

    说明

    【数据范围】 对于 $100\%$ 的数据,$1le n le 10^5$,$|x| le 10^7$ 来源:Tyvj1728 原名:普通平衡树 在此鸣谢

    /

    【结果】

    #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    #include<stdio.h>
    #include<set>
    using namespace std;
    int n;
    multiset<int>bbt;
    multiset<int>::iterator it;
    template<typename T>
    inline void read(T &x){
        register bool f=0;register char ch=getchar();x=0;
        for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
        for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch&15);
        if(f) x=-x;
    }
    template<typename T,typename...Args>
    inline void read(T &x,Args&...args){read(x);read(args...);}
    int main(){
    //    freopen("input.txt","r",stdin);
        read(n);
        for(int i=1,opt,k;i<=n;i++){
            read(opt,k);
            if(opt==1) bbt.insert(k);else
            if(opt==2) bbt.erase(bbt.lower_bound(k));else
            if(opt==3) printf("%d
    ",distance(bbt.begin(),bbt.lower_bound(k))+1);else
            if(opt==4) it=bbt.begin(),advance(it,k-1),printf("%d
    ",*it);else
            if(opt==5) printf("%d
    ",*--bbt.lower_bound(k));else
            if(opt==6) printf("%d
    ",*bbt.upper_bound(k));
        }
        return 0;
    }

    【分析】

    优点:使用IO的快读优化&手动开启Ofast优化
    缺陷:
    if(opt==3) printf("%d
    ",distance(bbt.begin(),bbt.lower_bound(k))+1);
    if(opt==4) it=bbt.begin(),advance(it,k-1),printf("%d
    ",*it);
    时间消耗主要在以上两项操作distance、advance(封装于algorithm),时间复杂度均为O(n)
    
    而pb_ds中的rb_tree在查询第k大和排名时封装了O(log n)的函数 参见这里
        
    除此之外,set还有求交集、并集、差集的操作,时间复杂度都为O(m+n),m,n分别为两个容器的大小
    事实上,任意有序容器皆可以(无序的可以先排序)
    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        set<int> s1, s2, S;
        s1.insert(1);
        s1.insert(2);
        s1.insert(3);
        s2.insert(2);
        s2.insert(3);
        s2.insert(4);
    
        S.clear();//clear before operation
        set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(S, S.begin()));
        puts("S=");
        for(auto &v : S)
            printf("%d ", v);
        puts("");
    
        S.clear();
        set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(S, S.begin()));
        puts("S=");
        for(auto &v : S)
            printf("%d ", v);
        puts("");
        
        vector<int> res(10,0);
        vector<int>::iterator iter;
        iter=set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(),res.begin());
        res.resize(iter-res.begin()); 
        puts("S=");
        for(iter=res.begin();iter!=res.end();++iter){
            cout<<*iter<<endl;
        }
        return 0; 
    }
    交集并集差集 示例

    注意!
    不要尝试用 less_equal做pb_ds的rb_tree的参数来解决平衡树中多值重复的麻烦。
    lower_bound与upper_bound都会有问题


    原则上讲STL中不要用less_equal,有些算法可能会出问题,尤其是涉及“等值”和“等价”的概念,如set、map等(内置红黑树的结构)。

    模板参数设为less_equal时,lower_bound永远不会返回和查找值一样的值,也就是说,find()函数永远不会返回end(),即查找失败。

    STL中的 sort, merge等,可以用less_equal,但不代表所有地方都行。与其记住哪些可以、哪些不可以,不如都用less 好了。
    sort以后,等值元素的顺序是不确定的,不同系统下给出的结果可能不同,除非使用同一版本的STL。

    单就这个例子,
    sort(vect.begin(), vect.end(), less<int>() );和
    sort(vect.begin(), vect.end(), less_equal<int>() );
    如果用less_equal,碰到2数相同时会多进行一次交换,浪费时间
     

  • 相关阅读:
    牛客网编程练习之网易2017校招题:下厨房
    牛客网编程练习之网易2017校招题:数字翻转
    牛客网编程练习之京东2017校招题:幸运数
    牛客网编程练习之去哪儿网2017校招题:身份证分组
    牛客网编程练习之网易2017校招题:解救小易
    牛客网编程练习之腾讯2017校招题:游戏任务标记
    Fiddler实现对手机抓包
    sshpass笔记
    图片反色
    LintCode题解之统计数字
  • 原文地址:https://www.cnblogs.com/shenben/p/12765517.html
Copyright © 2020-2023  润新知