<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;
}