__gnu_pbds::tree
See also: official documentation
#include <ext/pb_ds/assoc_container.hpp> // Because tree is defined here, this header must be included
#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>>
Template Parameters
Key: The type of stored elements. To store multiple elements with the sameKey, use a method such asstd::pairandstruct, together with thelower_boundandupper_boundmember functions for lookup.Mapped: The mapping-rule (Mapped-Policy) type. To make the associative container a set, similar to storing elements instd::set, usenull_typehere; in older versions ofg++, usenull_mapped_type. To make it a value-bearing set, similar tostd::map, use aValuetype likestd::map<Key, Value>.Cmp_Fn: A key-comparison functor, such asstd::less<Key>.Tag: Selects the type of underlying data structure; the default isrb_tree_tag.__gnu_pbdsprovides three different balanced trees:rb_tree_tag: a red-black tree; generally, this is the one to use, and the latter two generally have worse performance than a red-black treesplay_tree_tag: a splay treeov_tree_tag: an ordered vector tree; it is simply an ordered structure implemented with avector, similar to implementing a balanced tree with a sortedvector, and its performance depends on whether the data is designed to cause trouble
Node_Update: The node update policy, defaulting tonull_node_update; to use theorder_of_keyandfind_by_ordermethods, usetree_order_statistics_node_update.Allocator: The space allocator type.
Construction
__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>
trr;
Member Functions
insert(x): Inserts an elementxinto the tree and returnsstd::pair<point_iterator, bool>. The first element represents the iterator to the insertion position, and the second indicates whether insertion succeeded.erase(x): Deletes an element/iteratorxfrom the tree. Ifxis an iterator, it returns an iterator pointing to the element afterx(ifxisend(), it returnsend()); ifxis aKey, it returns whether deletion succeeded (if it does not exist, deletion fails).order_of_key(x): Returns the number of elements strictly less thanx(usingCmp_Fnas the comparison logic), namely the rank starting from .find_by_order(x): Returns the iterator to the element with the rank determined byCmp_Fn.lower_bound(x): Returns the iterator to the first element not less thanx(usingCmp_Fnas the comparison logic).upper_bound(x): Returns the iterator to the first element strictly greater thanx(usingCmp_Fnas the comparison logic).join(x): Merges treexinto the current tree and clears treex(the comparison functions and element types of the two trees must be the same).split(x,b): UsingCmp_Fnfor comparison, elements less than or equal toxbelong to the current tree, and the rest belong to treeb.empty(): Returns whether the tree is empty.size(): Returns the size.
Note
The join(x) function requires that the key value ranges of the tree being merged and the tree receiving it be disjoint (that is, all values in the merged tree must be either greater than or less than all values in the current tree); otherwise, it throws a join_error exception.
To merge two trees whose value ranges intersect, insert the elements of one tree into the other one by one.
Example
// Common Header Simple over C++11
#include <iostream>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int, int>;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
__gnu_pbds::tree<pair<int, int>, __gnu_pbds::null_type, less<pair<int, int>>,
__gnu_pbds::rb_tree_tag,
__gnu_pbds::tree_order_statistics_node_update>
trr;
int main() {
int cnt = 0;
trr.insert(make_pair(1, cnt++));
trr.insert(make_pair(5, cnt++));
trr.insert(make_pair(4, cnt++));
trr.insert(make_pair(3, cnt++));
trr.insert(make_pair(2, cnt++));
// Elements on the tree: {(1,0), (2,4), (3,3), (4,2), (5,1)}
auto it = trr.lower_bound(make_pair(2, 0));
trr.erase(it);
// Elements on the tree: {(1,0), (3,3), (4,2), (5,1)}
// Output the first of the element with rank 1 among ranks 0, 1, 2, and 3
auto it2 = trr.find_by_order(1);
cout << (*it2).first << endl; // Output: 3
// Output its rank
int pos = trr.order_of_key(*it2);
cout << pos << endl; // Output: 1
// Split trr at it2
decltype(trr) newtr;
trr.split(*it2, newtr);
for (auto i = newtr.begin(); i != newtr.end(); ++i) {
cout << (*i).first << ' '; // Output: 4 5
}
cout << endl;
// Merge tree newtr into tree trr; tree newtr is cleared.
trr.join(newtr);
for (auto i = trr.begin(); i != trr.end(); ++i) {
cout << (*i).first << ' '; // Output: 1 3 4 5
}
cout << endl;
cout << newtr.size() << endl; // Output: 0
return 0;
}