【算法板子】普通平衡树(洛谷P3369)

26 篇文章 1 订阅
26 篇文章 0 订阅
本文介绍了如何在C++中使用平衡树(如红黑树)进行数据操作,包括插入、删除、查询排名和获取特定下标的元素。示例代码展示了如何创建平衡树,并通过平衡树实现对有序序列的操作,如查询元素排名和找到第k小的数。此外,还演示了如何找到一个数的前驱和后继。
摘要由CSDN通过智能技术生成

<tree>平衡树

  • 需要包含头文件<ext/pb_ds/tree_policy.hpp><ext/pb_ds/assoc_container.hpp>

    或者直接#include <bits/extc++.h>

  • 创建下标和数值正相关平衡树的基本方法:(负相关只需要把less改成greater

    tree<double, null_type, less<double>, rb_tree_tag, tree_order_statistics_node_update> T;

    //对于:

    • tree<double, null_type, greater, rb_tree_tag, tree_order_statistics_node_update> T;

    //这个东西是有一点长
    //第一个参数是数据类型
    //第二个要填null_type,低版本编译器填null_mapped_type
    //第三个填比较函数 std::greater<> or std::less<> or cmp
    //第四个填树的类型,有rb_tree_tag红黑树和splay_tree_tag
    //第五个是为了支持查询第k大和排名的一个参数
    //tree_order_statistics_node_update

  • 基本操作有

T.insert();					//插入一个数x
T.erase(T.lower_bound(x));	//删除一个数x
T.order_of_key(x);			//查询x在树中的下标(排序后的下标)
*T.find_by_order(k);		//查询下标为k的数,返回它的迭代器
  • 因为这种tree和set一样不会保存相同的元素,所以在使用时我们可以加上i * 1e-6(其中i是输入时的下标or操作序,唯一就行)
#include<bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
 
// tree<double, null_mapped_type, greater<double>, rb_tree_tag, tree_order_statistics_node_update> T;
tree<double, null_type, less<double>, rb_tree_tag, tree_order_statistics_node_update> T;
 
int main()
{
    // //freopen("3369.in", "r", stdin);//洛谷
    // //freopen("3369.out", "w", stdout);
 
    int q, opt, x;
 
    scanf("%d", &q);
    for (int i = 1; i <= q; ++ i)
    {
        scanf("%d%d", &opt, &x);
        
        if(opt == 1) 
            T.insert(x + i * 1e-6);
        //插入一个数
        
        if(opt == 2) 
            T.erase(T.lower_bound(x));
        //删除一个数
        
        if(opt == 3) 
            printf("%d\n", (int)T.order_of_key(x) + 1);
        //查询一个数的排名
        
        if(opt == 4) 
            printf("%d\n", (int)*T.find_by_order(x - 1));
        //查询第k小的数 返回的是一个迭代器 这里k是从0开始算的,意思是最小的数是第0小的
        
        if(opt == 5) 
            printf("%d\n", (int)round(*(-- T.lower_bound(x))));
        //查询一个数的前驱
        
        if(opt == 6) 
            printf("%d\n", (int)round(*T.lower_bound(x + 1)));
        //查询一个数的后继
        
    }
 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值