pb_ds
2025-08-13 22:34:34
发布于:浙江
7阅读
0回复
0点赞
在放代码之前,先介绍一个库—— pbds(Policy-Based Data Structures),这是一个 GNU C++ STL 的扩展库,提供了增强版数据结构,包括优先队列,平衡树。
在 pbds 库中,有一个容器,叫 tree,是一种平衡二叉搜索树,可以支持按排名访问元素。
tree 容器
定义
template<
    typename Key,                           // 元素类型
    typename Mapped,                        // 映射值类型 (相当于 map 的映射值),模拟 set 时无需该项,设为 null_type即可
    typename Cmp_Fn,                        // 比较函数,例如 less<Key> 等,也可以使用自定义比较函数
    typename Tag,                           // 树类型 rb_tree_tag(红黑树,默认是这个) / splay_tree_tag
    template<typename Const_Node_Iterator,
             typename Node_Iterator,
             typename Cmp_Fn_,
             typename Allocator_>class Node_Update // 节点更新策略,例如 tree_order_statistics_node_update
>class tree;
使用前提
- 需要包含<ext/pb_ds/assoc_container.hpp>,<ext/pb_ds/tree_policy.hpp>头文件(注意,万能头文件中一般不含这两个头文件)。
- 使用 find_by_order或order_of_key函数时,必须使用tree_order_statistics_node_update策略。
- 默认去重,重复元素需用 pair<value,unique number> 处理。
核心功能/函数
| 功能 | 函数 | 说明 | 返回值/类型 | 时间复杂度 * | 
|---|---|---|---|---|
| 插入元素 | insert(x) | 插入元素 x(唯一) | void | O(log n) | 
| 删除元素 | erase(x) | 删除值等于 x 的元素 | void | O(log n) | 
| 查找元素 | find(x) | 返回迭代器 | iterator | O(log n) | 
| 查找第 k 小 | find_by_order(k) | 返回第 k 小元素,0-index | iterator | O(log n) | 
| 查询排名 | order_of_key(x) | 返回严格小于 x 的元素数量 | int | O(log n) | 
| 大小 | size() | 当前元素个数 | int | O(1) | 
| 是否为空 | empty() | 检查是否为空 | bool | O(1) | 
| 清空 | clear() | 删除所有元素 | void | O(n) | 
*:时间复杂度是在 rb_tree_tag 的基础上计算的。
『题解』A21561中位数
题目大意
题目等价于:动态维护前i个元素的有序序列,快速取第k小元素。
- 中位数的下标 (1-indexed)。
- 输入 ,元素范围 。
代码实现
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define int long long
using namespace std;
using namespace __gnu_pbds;//使用 __gnu_pbds 命名空间
tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update>s;//定义一棵平衡树
signed main() 
{
    int n;
    cin>>n;
    for (int i=1;i<=n;i++) 
    {
        int x;
        cin>>x;
        s.insert({x,i});//将每一个值插入树中,i 避免重复
        if(i%2==1) //如果是奇数项
        {
            cout<<s.find_by_order(i/2)->first<<"\n";//输出排名为 i/2 的项的值,即前 1~i 位的中位数
        }
    }
    return 0;
}
时间复杂度
。
这里空空如也


有帮助,赞一个