-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
176 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
<!DOCTYPE html> | ||
<html lang="zh"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="author" content="Gaolei He"> | ||
<meta name="description" content="how to use C++::PBDS"> | ||
<title>PBDS</title> | ||
</head> | ||
|
||
<body> | ||
<h1><b>PBDS</b></h1> | ||
<hr> | ||
<h2><code style="background-color: #dfdfdf;">__gnu_pbds::tree</code></h2> | ||
<p> | ||
<table cellPadding="10px"> | ||
<tr> | ||
<td> | ||
<font color="#000000"> | ||
<font face="monospace"> | ||
<pre style="background-color: #dfdfdf;"> | ||
#include <ext/pb_ds/assoc_container.hpp> // 因为tree定义在这里 所以需要包含这个头文件 | ||
#include <ext/pb_ds/tree_policy.hpp> | ||
using namespace __gnu_pbds; | ||
__gnu_pbds ::tree<Key, Mapped, Cmp_Fn = std::less<Key>, Tag = rb_tree_tag, | ||
Node_Update = null_tree_node_update, | ||
Allocator = std::allocator<char> > | ||
</pre> | ||
</font> | ||
</font> | ||
</td> | ||
</tr> | ||
</table> | ||
</p> | ||
|
||
<hr> | ||
<h2>模板形参</h2> | ||
<ul> | ||
<li><code style="background-color: #dfdfdf;">Key</code>:储存的元素类型,如果想要存储多个相同的 <code | ||
style="background-color: #dfdfdf;">Key</code> 元素,则需要使用类似于 <code | ||
style="background-color: #dfdfdf;">std::pair</code> 和 <code | ||
style="background-color: #dfdfdf;">struct</code> 的方法,并配合使用 <code | ||
style="background-color: #dfdfdf;">lower_bound</code> 和 <code | ||
style="background-color: #dfdfdf;">upper_bound</code> 成员函数进行查找</li> | ||
<li><code style="background-color: #dfdfdf;">Mapped</code>: 映射规则(Mapped-Policy)类型,如果要指示关联容器是 集合,类似于存储元素在 <code style="background-color: #dfdfdf;">std::set</code> 中,此处填入 | ||
<code style="background-color: #dfdfdf;">null_type</code> ,低版本 <code style="background-color: #dfdfdf;">g++</code> 此处为 <code style="background-color: #dfdfdf;">null_mapped_type</code> ;如果要指示关联容器是 | ||
<b>带值的集合</b>,类似于存储元素在 <code style="background-color: #dfdfdf;">std::map</code> 中,此处填入类似于 <code style="background-color: #dfdfdf;">std::map<Key, Value></Key></code> 的 | ||
<code style="background-color: #dfdfdf;">Value</code> 类型 | ||
</li> | ||
<li><code style="background-color: #dfdfdf;">Cmp_Fn</code>: 关键字比较函子,例如 <code style="background-color: #dfdfdf;">std::less<Key></code></li> | ||
<li><code style="background-color: #dfdfdf;">Tag</code>: 选择使用何种底层数据结构类型,默认是 <code style="background-color: #dfdfdf;">rb_tree_tag</code>。<code style="background-color: #dfdfdf;">__gnu_pbds </code> 提供不同的三种平衡树,分别是: | ||
<ul> | ||
<li><code style="background-color: #dfdfdf;">rb_tree_tag</code>:红黑树,一般使用这个,后两者的性能一般不如红黑树</li> | ||
<li><code style="background-color: #dfdfdf;">splay_tree_tag</code>:splay 树</li> | ||
<li><code style="background-color: #dfdfdf;">ov_tree_tag</code>:有序向量树,只是一个由 vector 实现的有序结构,类似于排序的 <code style="background-color: #dfdfdf;">vector </code> 来实现平衡树,性能取决于数据想不想卡你 | ||
</li> | ||
</ul> | ||
</li> | ||
<li><code style="background-color: #dfdfdf;">Node_Update</code>:用于更新节点的策略,默认使用 <code style="background-color: #dfdfdf;">null_node_update</code>,若要使用 <code style="background-color: #dfdfdf;">order_of_key </code>和 | ||
<code style="background-color: #dfdfdf;">find_by_order </code>方法,需要使用 <code style="background-color: #dfdfdf;">tree_order_statistics_node_update</code></li> | ||
<li><code style="background-color: #dfdfdf;">Allocator</code>:空间分配器类型</li> | ||
</ul> | ||
|
||
<hr> | ||
|
||
<h2>构造方式</h2> | ||
<p> | ||
<table cellPadding="10px"> | ||
<tr> | ||
<td> | ||
<font color="#000000"> | ||
<font face="monospace"> | ||
<pre style="background-color: #dfdfdf;"> | ||
__gnu_pbds::tree<std::pair<int, int>, __gnu_pbds::null_type, | ||
std::less<std::pair<int, int> >, __gnu_pbds::rb_tree_tag, | ||
__gnu_pbds::tree_order_statistics_node_update> tr; | ||
</pre> | ||
</font> | ||
</font> | ||
</td> | ||
</tr> | ||
</table> | ||
</p> | ||
|
||
<hr> | ||
|
||
<h2>成员函数</h2> | ||
|
||
<ul> | ||
<li><code style="background-color: #dfdfdf;">insert(x)</code>:向树中插入一个元素 <code style="background-color: #dfdfdf;">x</code>,返回 <code style="background-color: #dfdfdf;">std::pair<point_iterator, bool></code>。</li> | ||
<li><code style="background-color: #dfdfdf;">erase(x)</code>:从树中删除一个元素/迭代器 <code style="background-color: #dfdfdf;">x</code>,返回一个 <code style="background-color: #dfdfdf;">bool</code> 表明是否删除成功。</li> | ||
<li><code style="background-color: #dfdfdf;">order_of_key(x)</code>:返回 <code style="background-color: #dfdfdf;">x</code> 以 <code style="background-color: #dfdfdf;">Cmp_Fn</code> 比较的排名。</li> | ||
<li><code style="background-color: #dfdfdf;">find_by_order(x)</code>:返回 <code style="background-color: #dfdfdf;">Cmp_Fn</code> 比较的排名所对应元素的迭代器。</li> | ||
<li><code style="background-color: #dfdfdf;">lower_bound(x)</code>:以 <code style="background-color: #dfdfdf;">Cmp_Fn</code> 比较做 <code style="background-color: #dfdfdf;">lower_bound</code>,返回迭代器。</li> | ||
<li><code style="background-color: #dfdfdf;">upper_bound(x)</code>:以 <code style="background-color: #dfdfdf;">Cmp_Fn</code> 比较做 <code style="background-color: #dfdfdf;">upper_bound</code>,返回迭代器。</li> | ||
<li><code style="background-color: #dfdfdf;">join(x)</code>:将 <code style="background-color: #dfdfdf;">x</code> 树并入当前树,前提是两棵树的类型一样,<code style="background-color: #dfdfdf;">x</code> 树被删除。</li> | ||
<li><code style="background-color: #dfdfdf;">split(x,b)</code>:以 <code style="background-color: #dfdfdf;">Cmp_Fn</code> 比较,小于等于 <code style="background-color: #dfdfdf;">x</code> 的属于当前树,其余的属于 <code style="background-color: #dfdfdf;">b</code> 树。</li> | ||
<li><code style="background-color: #dfdfdf;">empty()</code>:返回是否为空。</li> | ||
<li><code style="background-color: #dfdfdf;">size()</code>:返回大小。</li> | ||
<li><code style="background-color: #dfdfdf;">find(x)</code>:返回指向 <code style="background-color: #dfdfdf;">x</code> 的迭代器,如果不存在则返回 <code style="background-color: #dfdfdf;">tree.end()</code></li> | ||
</ul> | ||
|
||
<hr> | ||
|
||
<h2>示例</h2> | ||
<p> | ||
<table cellPadding="10px"> | ||
<tr> | ||
<td> | ||
<font color="#000000"> | ||
<font face="monospace"> | ||
<pre style="background-color: #dfdfdf;"> | ||
#include <ext/pb_ds/assoc_container.hpp> | ||
#include <ext/pb_ds/tree_policy.hpp> | ||
#include <iostream> | ||
using namespace std; | ||
using namespace __gnu_pbds; | ||
int main() | ||
{ | ||
tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> tr; | ||
tr.insert(1); | ||
tr.insert(2); | ||
tr.insert(4); | ||
// 树中元素 1,2,4 | ||
auto it = tr.insert(3); // pair<point_iterator, bool> | ||
cout << *it.first << endl; // 3 | ||
cout << it.second << endl; // 1 | ||
|
||
bool flag = tr.erase(3); // bool | ||
cout << flag << endl; // 1 | ||
|
||
// 树中元素 1,2,4 | ||
// order_of_key(x) 返回小于x的元素个数(int) | ||
int cnt = tr.order_of_key(3); | ||
cout << cnt << endl; // 2 | ||
cnt = tr.order_of_key(2); | ||
cout << cnt << endl; // 1 | ||
|
||
// 树中元素 1,2,4 | ||
// find_by_order(k) 返回指向第k小的元素的迭代器 (从0开始) | ||
auto it2 = tr.find_by_order(1); // point_iterator | ||
cout << *it2 << endl; // 2 | ||
|
||
auto it3 = tr.lower_bound(2); // point_iterator | ||
cout << *it3 << endl; // 2 | ||
it3 = tr.upper_bound(2); // point_iterator | ||
cout << *it3 << endl; // 4 | ||
|
||
tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> tr1; | ||
tr1.insert(8); | ||
tr1.insert(16); | ||
tr1.insert(32); | ||
|
||
// tr.join(tr1) 将tr1合并到tr中,tr1中的元素会被删除 | ||
tr.join(tr1); | ||
for(auto it : tr) | ||
cout << it << endl; // 1 2 4 8 16 32 | ||
|
||
tr.split(4, tr1); // 将tr中小于等于4的元素分离出来,放到tr1中 | ||
for(auto it : tr) | ||
cout << it << endl; // 1, 2, 4 | ||
|
||
return 0; | ||
} | ||
</pre> | ||
</font> | ||
</font> | ||
</td> | ||
</tr> | ||
</table> | ||
</p> | ||
</body> | ||
|
||
|
||
</html> |