什么是pb_ds?

除了众所周知的STL库,c++还自带了ext库(应该可以这么叫吧),其中有用pb_ds命名的名称空间(俗称平板电视)。这个名称空间下有四个数据类型结构。这些都是鲜为人知的。经过测试目前所有的OJ都支持pb_ds库,OI据说也支持。网上资料显示只要是稍微高级一点的linux判卷机都是支持的。这个库的网上资料甚少,百度wiki也没有找到相关的词条,我靠东拼西凑凑出来这么一篇不成形的博客,以后也会继续研究更新

pb_ds包含的数据结构

导言

要想运用pb_ds库有两种方法

①直接使用

#include<bits/extc++.h>
using namespace __gnu_pbds;//两个_在gnu前面

但是可惜的是这个头文件大部分的oj还是不支持的,并且本地的dev也不支持,所以还是不要这么写的好

②按照需求写头文件

#include <bits/stdc++.h>
#include <ext/pb_ds/assco_container.hpp>//这个必须在各个pb_ds的数据结构之前写,不知道为啥
using namespace __gnu_pbds;

①哈希

哈希大家都知道,就是一种映射。但是我们STL中已经有map了,这个还有什么用呢?实际上根据网上资料显示这个hash_table比map要快map是nlogn这个是n。

头文件

#include <ext/pb_ds/hash_policy.hpp>

定义方法有两种

cc_hash_table<int,bool> h;
gp_hash_table<int,bool> h;

根据网上的大佬评测后者速度更快一些。

具体用法跟map相似不在赘述,下面摆一个示例用pb_ds库中的哈希做的a+b且在QLUOJ上通过

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
gp_hash_table<long long,long long> mp;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
long long a,b;
cin>>a>>b;
mp[0]=a;
mp[1]=b;
cout<<mp[0]+mp[1];
}

感觉可以是map的上位替换

②堆(优先队列)

基本运用与STL的优先队列没有什么其他的区别,多了堆的合并操作和分离操作

头文件

#include <ext/pb_ds/priority_queue_policy,hpp>//真的长

定义方法

priority_queue<int,greater<int>,TAG> Q;
第一个参数是数据类型
第二个是排序方式
第三个是堆的类型
其中堆的类型有下面几种
pairing_heap_tag
thin_heap_tag
binomial_heap_tag
rc_binomial_heap_tag
binary_heap_tag
其中pairing_heap_tag最快
并且这个东西是带默认参数的,只需要定义一个int也可以

①join函数

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
//using namespace __gnu_pbds;
__gnu_pbds::priority_queue<int> a,b;//注意这个地方为了避免与std的stl发生冲突,所以带上名称空间
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
while(n--)
{
int t1;
cin>>t1;
a.push(t1);
}
while(m--)
{
int t1;
cin>>t1;
b.push(t1);
}
a.join(b);
while(a.size())
{
cout<<a.top()<<" ";
a.pop();
}
}

这样会把两个优先队列合并成一个,b优先队列清空

结果

②split函数用法

此处省略,材料过少无法知道split函数的第一个参数的具体意思

③trie字典树

我觉得完全没有什么卵用的东西,只能完成基本的模板操作,而且不知道为啥我试了试还超时,是不是我姿势不对,网上也说没啥用

头文件

#include<ext/pb_ds/trie_policy.hpp>

具体用法(这里复制了洛谷日报第三十九期)

typedef trie<string,null_type,trie_string_access_traits<>,pat_trie_tag,trie_prefix_search_node_update> tr;
//第一个参数必须为字符串类型,tag也有别的tag,但pat最快,与tree相同,node_update支持自定义
tr.insert(s); //插入s
tr.erase(s); //删除s
tr.join(b); //将b并入tr
pair//pair的使用如下:
pair<tr::iterator,tr::iterator> range=base.prefix_range(x);
for(tr::iterator it=range.first;it!=range.second;it++)
cout<<*it<<' '<<endl;
//pair中第一个是起始迭代器,第二个是终止迭代器,遍历过去就可以找到所有字符串了。

遍历一个前缀所包含的单词数(hdu1251 TLE)可能是我的操作问题。。。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/trie_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef trie<string,null_type,trie_string_access_traits<>,pat_trie_tag,trie_prefix_search_node_update> tr;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
tr base;
string a;
while(getline(cin,a))
{
if(a.size()==0)
break;
else
base.insert(a);
}
string b;
while(getline(cin,b))
{
int sum=0;
auto range=base.prefix_range(b);
for(auto it=range.first;it!=range.second;it++)
sum++;
cout<<sum<<"\n";
}
}

反正trie建议手搓

④平衡树

这个真心的感觉是这里面最牛逼的,所以我放倒了压轴的位置。唯一需要注意的是这个平衡树是set的形状,也就是说他是会自动去重的。。。当然也可以不自动去重,但是目前我还没有研究出来

头文件

#include <ext/pb_ds/tree_policy.hpp>

具体用法

可以理解为是set++
tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> tr;
第一个参数是数据类型
第二个参数是没有映射直接照抄即可
第三个排序方式
第四个是平衡树的类型,这里网上一致认为红黑树最快,好像比手搓的还快?
第五个是自定义节点更新方式(这个可以自定义,但是我目前不会) //这一部分更改于洛谷日报第39期
tr.insert(x); //插入;
tr.erase(x); //删除;
tr.order_of_key(x); //求排名
tr.find_by_order(x-1); //找k小值,返回迭代器
tr.join(b); //将b并入tr,前提是两棵树类型一样且没有重复元素
tr.split(v,b); //分裂,key小于等于v的元素属于tr,其余的属于b
tr.lower_bound(x); //返回第一个大于等于x的元素的迭代器
tr.upper_bound(x); //返回第一个大于x的元素的迭代器
//以上所有操作的时间复杂度均为O(logn)

完整代码

1.插入x数
2.删除x数(若有多个相同的数,因只删除一个)
3.查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
4.查询排名为x的数
5.求x的前驱(前驱定义为小于x,且最大的数)
6.求x的后继(后继定义为大于x,且最小的数)
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> a;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
while(n--)
{
int t1,t2;
cin>>t1>>t2;
if(t1==1)
a.insert(t2);
else if(t1==2)
a.erase(t2);
else if(t1==3)
cout<<a.order_of_key(t2)<<"\n";
else if(t1==4)
cout<<*a.find_by_order(t2-1)<<"\n";
else if(t1==5)
cout<<*--a.lower_bound(t2)<<"\n";
else if(t1==6)
cout<<*a.upper_bound(t2)<<"\n";
}
}

STL++?pb_ds平板电视初步探索的更多相关文章

  1. NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索

    一.主从复制架构简介 通过前面几篇的介绍中,我们都是在单机上使用Redis进行相关的实践操作,从本篇起,我们将初步探索一下Redis的集群,而集群中最经典的架构便是主从复制架构.那么,我们首先来了解一 ...

  2. 【转】 NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索

    一.主从复制架构简介 通过前面几篇的介绍中,我们都是在单机上使用Redis进行相关的实践操作,从本篇起,我们将初步探索一下Redis的集群,而集群中最经典的架构便是主从复制架构.那么,我们首先来了解一 ...

  3. 企查查app 初步探索

    企查查app sign算法破解初步探索 之前有说过企查查的sign的解密,但这次是企查查app的sign算法破解,目前是初步进程. 已删除!!!! 上边一些变量已经找到了,其中就有时间戳,其余两个需要 ...

  4. Springboot与ActiveMQ、Solr、Redis中分布式事物的初步探索

    Springboot与ActiveMQ.Solr.Redis中分布式事物的初步探索 解决的场景:事物中的异步问题,当要求数据库与solr服务器的最终一致时. 程序条件: 利用消息队列,当数据库添加成功 ...

  5. 侯捷STL学习(八)-- 深度探索deque

    layout: post title: 侯捷STL学习(八) date: 2017-07-19 tag: 侯捷STL --- 第十八节 深度探索deque上 duque内存结构 分段连续,用户看起来是 ...

  6. 侯捷STL学习(七)--深度探索vector&&array

    layout: post title: 侯捷STL学习(七) date: 2017-06-13 tag: 侯捷STL --- 第十六节 深度探索vector vector源码剖析 vector内存2倍 ...

  7. ASP.Net请求处理机制初步探索之旅 - Part 1 前奏

    开篇:ASP.Net是一项动态网页开发技术,在历史发展的长河中WebForm曾一时成为了ASP.Net的代名词,而ASP.Net MVC的出现让这项技术更加唤发朝气.但是,不管是ASP.Net Web ...

  8. ASP.Net请求处理机制初步探索之旅 - Part 2 核心

    开篇:上一篇我们了解了一个请求从客户端发出到服务端接收并转到ASP.Net处理入口的过程,这篇我们开始探索ASP.Net的核心处理部分,借助强大的反编译工具,我们会看到几个熟悉又陌生的名词(类):Ht ...

  9. swiper初步探索

    最近要做一个效果,初步想到了使用swiper,不过貌似最后并不能完全通过swiper来实现,整整试了一天的时间都没有试出来,真是...压力很大,不过自己选的路,总要坚持走下去了. Swiper(Swi ...

随机推荐

  1. ios30---pthread, NSThread, GCD, NSOperation

    pthread(线程库,很早就有的技术,了解):一套通用的多线程API适用于Unix\Linux\Windows等系统(java开发也有pthread)跨平台\可移植使用难度大(全是C函数) C语言 ...

  2. 怎么在当前的view上获取所在的控制器(UIViewController),实现跳转

    - (UIViewController *)viewController { for (UIView* next = [self superview]; next; next = next.super ...

  3. bzoj 4337 树的同构

    4337: BJOI2015 树的同构 Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树 ...

  4. 【JSOI 2011】 分特产

    [题目链接] 点击打开链接 [算法] 考虑求每个人可以不分的方案 那么,对于每件物品,我们把它分成n份,每一份对应分给每一个人,有C(a[i]+n-1,m-1)种方案,而总方案数就是每种 物品方案数的 ...

  5. CMake使用总结

    总结CMake的常用命令,并介绍有用的CMake资源. CMake意为cross-platform make,可用于管理c/c++工程.CMake解析配置文件CMakeLists.txt生成Makef ...

  6. Java序列化系列教程(下)

    一引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口 ...

  7. 如何在BCGControlBar工程的工具栏里面新增下拉列表控件

    通常情况下,工具栏里面都是一些按钮和图片,很少可以看到下拉列表控件,但是在某些应用场合,也需要用到下拉列表控件.今天在这里就简单讲解下如何在工具栏里添加下拉列表控件.   添加的过程也比较简单,在CM ...

  8. 谈CSS布局中HTML标签语义化

    很多人都在做前端,当然这里包括很多新手,也许在新手的想法就是在做布局的时候不要用font标签之类的就算是web标准了,这样一来,造成如今网上“div泛滥”,一看源文件,霍,除了div没其他标签了. 这 ...

  9. attr 和 prop的区别和使用

    一. attr和prop的区别 要想弄清楚attr和prop的区别,就要先搞清楚js中使用DOM方法获取设置属性和使用对象方法获取设置属性的区别. 在javascript中使用DOM方法设置获取属性值 ...

  10. 代码中特殊的注释技术——TODO、FIXME和XXX的用处 (转载)

    转自:http://blog.csdn.net/reille/article/details/7161942 作者:reille 本博客网址:http://blog.csdn.net/reille/, ...