pb_ds库的讲解和应用举例
来源:互联网 发布:线条随鼠标特效源码 编辑:程序博客网 时间:2024/06/10 08:28
之前玩了玩bp_ds库,发现它的确有好用之处,却也有一些缺陷。
这里只介绍了一些常用用法,详情请见:https://gcc.gnu.org/onlinedocs/libstdc%2B%2B/ext/pb_ds/
1、hash
pbds自带两种hash,分别用的拉链法和查探法,后者要快一些(和我手打的差不多),而且空间更少(见后文例题),所以推荐后者。
头文件:
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
用法:
cc_hash_table是拉链法
gp_hash_table是查探法
除了当数组用外,还支持find和operator[]
例如:__gnu_pbds::gp_hash_table<int,bool> h;
例题:
#include<cstdio>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/hash_policy.hpp>__gnu_pbds::gp_hash_table<int,bool> h;inline int read(){int r=0;char c=getchar();while(c<'0'||c>'9') {c=getchar();}while(c>='0'&&c<='9') {r=r*10+c-'0';c=getchar();}return r;}int main(){int n=read(),m=read(),k;while(n--){k=read();h[k]=true;}while(m--){k=read();puts(h[k]?"YES":"NO");}return 0;}
2、堆
头文件:
#include<ext/pb_ds/priority_queue.hpp>
用法:
主要用pairing_heap_tag,配对堆,比thin_heap_tag快
和::priority queue用法大致相同,但多了可并堆的join(), modify() , erase() 等
例如: __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> pq;
less是stl里的比较器,需要using namespace std, 也可以换成 greater。
例题:
bzoj 3040: 最短路(road)
#include<iostream>#include<algorithm>#include<climits>#include<cstdio>#include<ext/pb_ds/priority_queue.hpp>using namespace std;using namespace __gnu_pbds;typedef long long ll;const int M=1000005;inline int read(){ int r=0;char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') {r=r*10+c-'0';c=getchar();} return r;}struct node{ int i; ll v; node(int a=0,ll c=0){i=a;v=c;} bool operator < (node b) const { return v>b.v; }};typedef __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> heap;//!!!heap::point_iterator hit[M];heap pq;int n;ll d[M];int last[1000005],cnt;struct data{int to,next,v;}e[10000005];void insert(int u,int v,int w){ e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;}inline void setpath(){ int T,rxa,rxc,rya,ryc,rp,x,y,z,m; x=y=z=0; n=read();m=read(); T=read();rxa=read();rxc=read();rya=read();ryc=read();rp=read(); int a,b,q=min(n,T); for(int i=0;i<q;i++) { x=((ll)x*rxa+rxc)%rp; y=((ll)y*rya+ryc)%rp; a=min(x%n+1,y%n+1); b=y%n+1; insert(a,b,100000000-100*a); } for(int i=0;i<m-T;i++) { x=read(),y=read(),z=read(); insert(x,y,z); }}ll dijkstra(){ for(int i=1;i<=n;i++) d[i]=LLONG_MAX; hit[1]=pq.push(node(1,0)); d[1]=0; int o; while(!pq.empty()) { o=pq.top().i; pq.pop(); if(o==n) return d[o]; for(int i=last[o];i;i=e[i].next) { if(d[e[i].to]>d[o]+e[i].v) { d[e[i].to]=d[o]+e[i].v; if(hit[e[i].to]==0) hit[e[i].to]=pq.push(node(e[i].to,d[e[i].to])); else pq.modify(hit[e[i].to],node(e[i].to,d[e[i].to])); } } }}int main(){ setpath(); cout<<dijkstra(); return 0;}
3、平衡树
pbds最大的好处在于支持名次树和自定义函数
头文件:
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
用法:
常用rb_tree_tag(红黑数)和splay_tree_tag
可以加tree_order_statistics_node_update以实现名次数
注意他没有multiset一样的功能,如果要存重复元素可以建结构体(见例题)。
相比set多了find_by_order和order_of_key(详见例题)
例如:tree<node,null_type,greater<node>,rb_tree_tag,tree_order_statistics_node_update> T;
注意老版本编译器要把null_type换成null_mapped_type。
例题:
#include<cstdio>#include<iostream>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>using namespace __gnu_pbds;using namespace std;struct node{int v,id;node(int a,int b){v=a;id=b;}bool operator >(node b) const{return v==b.v?id>b.id:v>b.v;}};tree<node,null_mapped_type,greater<node>,rb_tree_tag,tree_order_statistics_node_update> T,TE;int main(){int n,m,k,s=0,q,ans=0;char c[10];scanf("%d%d",&n,&m);while(n--){cin>>c[0];scanf("%d",&k);if(*c=='I') {k+=s;if(k>=m) T.insert(node(k,n));}else if(*c=='A') m-=k,s-=k;else if(*c=='S'){m+=k,s+=k;T.split(node(m,-1),TE);ans+=TE.size();}else if(*c=='F')printf(k>T.size()?"-1\n":"%d\n",T.find_by_order(k-1)->v-s);}printf("%d\n",ans);return 0;}
4、字典树
这个基本没用,就不讲了。。。- pb_ds库的讲解和应用举例
- 平板电视(pb_ds)应用
- 学习一个pb_ds库
- 关于C++ pb_ds库
- CppUnit的代码模拟和应用举例
- String和StringBuffer的应用举例
- find和grep的简单应用举例
- 举例讲解returnValue的含义
- 举例讲解returnValue的含义
- 举例讲解returnValue的含义
- JAVA多线程的应用场景和应用目的举例
- JAVA多线程的应用场景和应用目的举例
- JAVA多线程的应用场景和应用目的举例
- Java线性代数库jblas的应用举例
- 定时器的应用举例
- StringBuffer的应用举例
- 栈的应用举例
- 队列的应用举例
- JAVA基础训练之模拟双色球实现案列
- Android《第一行代码》第4章 笔记
- java多态使用时,如果想要调用子类特有属性如何做.
- 字符串操作
- 全国政协十二届五次会议开幕,汪国新委员出席并听取会议报告
- pb_ds库的讲解和应用举例
- scrapy框架爬取51job网
- php 与java在实现抽象方法上的不同
- Lucene Field域的详解(二)
- java正则表达式详解
- concat方法
- BDD1.4更换Logo图片
- JavaScript—定义 getters 与 setters
- 如何确定特定情况下可变参数函数的参数个数