From 672ee8a30b3ede271c6dde255d0a04793295df3e Mon Sep 17 00:00:00 2001 From: Oleksandr Kulkov Date: Sat, 10 Feb 2024 18:16:41 +0100 Subject: [PATCH] restructure lib files --- {src => cp-algo}/algebra/README.md | 0 .../common.cpp => cp-algo/algebra/common.hpp | 9 +- .../fft.cpp => cp-algo/algebra/fft.hpp | 24 +++-- .../matrix.cpp => cp-algo/algebra/matrix.hpp | 39 ++++--- .../algebra/modular.hpp | 14 ++- .../algebra/polynomial.hpp | 101 ++++++++++-------- .../data_structures/segment_tree.hpp | 8 +- .../data_structures/treap.hpp | 9 +- 8 files changed, 123 insertions(+), 81 deletions(-) rename {src => cp-algo}/algebra/README.md (100%) rename src/algebra/common.cpp => cp-algo/algebra/common.hpp (85%) rename src/algebra/fft.cpp => cp-algo/algebra/fft.hpp (88%) rename src/algebra/matrix.cpp => cp-algo/algebra/matrix.hpp (82%) rename src/algebra/modular.cpp => cp-algo/algebra/modular.hpp (88%) rename src/algebra/polynomial.cpp => cp-algo/algebra/polynomial.hpp (91%) rename src/data_structures/segment_tree.cpp => cp-algo/data_structures/segment_tree.hpp (91%) rename src/data_structures/treap.cpp => cp-algo/data_structures/treap.hpp (95%) diff --git a/src/algebra/README.md b/cp-algo/algebra/README.md similarity index 100% rename from src/algebra/README.md rename to cp-algo/algebra/README.md diff --git a/src/algebra/common.cpp b/cp-algo/algebra/common.hpp similarity index 85% rename from src/algebra/common.cpp rename to cp-algo/algebra/common.hpp index f055fad..8ae0f6d 100644 --- a/src/algebra/common.cpp +++ b/cp-algo/algebra/common.hpp @@ -1,7 +1,11 @@ -namespace algebra { // common +#ifndef ALGEBRA_COMMON_HPP +#define ALGEBRA_COMMON_HPP +#include +#include +namespace algebra { const int maxn = 1 << 20; const int magic = 250; // threshold for sizes to run the naive algo - mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); + std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count()); auto bpow(auto x, int64_t n, auto ans) { for(; n; n /= 2, x = x * x) { @@ -57,3 +61,4 @@ namespace algebra { // common return F[n]; } } +#endif // ALGEBRA_COMMON_HPP diff --git a/src/algebra/fft.cpp b/cp-algo/algebra/fft.hpp similarity index 88% rename from src/algebra/fft.cpp rename to cp-algo/algebra/fft.hpp index 5f19ce7..f5dfa4b 100644 --- a/src/algebra/fft.cpp +++ b/cp-algo/algebra/fft.hpp @@ -1,4 +1,9 @@ -namespace algebra { // fft +#ifndef ALGEBRA_FFT_HPP +#define ALGEBRA_FFT_HPP +#include "common.hpp" +#include "modular.hpp" +#include +namespace algebra { namespace fft { using ftype = double; struct point { @@ -66,7 +71,7 @@ namespace algebra { // fft } } - void mul_slow(vector &a, const vector &b) { + void mul_slow(std::vector &a, const std::vector &b) { if(a.empty() || b.empty()) { a.clear(); } else { @@ -75,7 +80,7 @@ namespace algebra { // fft a.resize(n + m - 1); for(int k = n + m - 2; k >= 0; k--) { a[k] *= b[0]; - for(int j = max(k - n + 1, 1); j < min(k + 1, m); j++) { + for(int j = std::max(k - n + 1, 1); j < std::min(k + 1, m); j++) { a[k] += a[k - j] * b[j]; } } @@ -85,9 +90,9 @@ namespace algebra { // fft template struct dft { static constexpr int split = 1 << 15; - vector A; + std::vector A; - dft(vector> const& a, size_t n): A(n) { + dft(std::vector> const& a, size_t n): A(n) { for(size_t i = 0; i < min(n, a.size()); i++) { A[i] = point( a[i].rem() % split, @@ -103,9 +108,9 @@ namespace algebra { // fft assert(A.size() == B.A.size()); size_t n = A.size(); if(!n) { - return vector>(); + return std::vector>(); } - vector C(n), D(n); + std::vector C(n), D(n); for(size_t i = 0; i < n; i++) { C[i] = A[i] * (B[i] + B[(n - i) % n].conj()); D[i] = A[i] * (B[i] - B[(n - i) % n].conj()); @@ -115,7 +120,7 @@ namespace algebra { // fft reverse(begin(C) + 1, end(C)); reverse(begin(D) + 1, end(D)); int t = 2 * n; - vector> res(n); + std::vector> res(n); for(size_t i = 0; i < n; i++) { modular A0 = llround(C[i].real() / t); modular A1 = llround(C[i].imag() / t + D[i].imag() / t); @@ -141,7 +146,7 @@ namespace algebra { // fft } template - void mul(vector> &a, vector> b) { + void mul(std::vector> &a, std::vector> b) { if(min(a.size(), b.size()) < magic) { mul_slow(a, b); return; @@ -156,3 +161,4 @@ namespace algebra { // fft } } } +#endif // ALGEBRA_FFT_HPP diff --git a/src/algebra/matrix.cpp b/cp-algo/algebra/matrix.hpp similarity index 82% rename from src/algebra/matrix.cpp rename to cp-algo/algebra/matrix.hpp index 53fd4fe..9d1f74f 100644 --- a/src/algebra/matrix.cpp +++ b/cp-algo/algebra/matrix.hpp @@ -1,12 +1,18 @@ - -namespace algebra { // matrix +#ifndef ALGEBRA_MATRIX_HPP +#define ALGEBRA_MATRIX_HPP +#include "common.hpp" +#include "modular.hpp" +#include +#include +#include +namespace algebra { template struct matrix { using base = modular; size_t n, m; - valarray> a; - matrix(size_t n, size_t m): n(n), m(m), a(valarray(m), n) {} - matrix(valarray> a): n(size(a)), m(n ? size(a[0]) : 0), a(a) {} + std::valarray> a; + matrix(size_t n, size_t m): n(n), m(m), a(std::valarray(m), n) {} + matrix(std::valarray> a): n(size(a)), m(n ? size(a[0]) : 0), a(a) {} auto& operator[] (size_t i) {return a[i];} auto const& operator[] (size_t i) const {return a[i];} @@ -20,7 +26,7 @@ namespace algebra { // matrix void read() { for(size_t i = 0; i < n; i++) { for(size_t j = 0; j < m; j++) { - cin >> (*this)[i][j]; + std::cin >> (*this)[i][j]; } } } @@ -28,7 +34,7 @@ namespace algebra { // matrix void print() const { for(size_t i = 0; i < n; i++) { for(size_t j = 0; j < m; j++) { - cout << (*this)[i][j] << " \n"[j + 1 == m]; + std::cout << (*this)[i][j] << " \n"[j + 1 == m]; } } } @@ -46,15 +52,15 @@ namespace algebra { // matrix assert(n == b.n); matrix res(n, m+b.m); for(size_t i = 0; i < n; i++) { - res[i][slice(0,m,1)] = a[i]; - res[i][slice(m,b.m,1)] = b[i]; + res[i][std::slice(0,m,1)] = a[i]; + res[i][std::slice(m,b.m,1)] = b[i]; } return res; } matrix submatrix(auto slicex, auto slicey) const { - valarray res = a[slicex]; + std::valarray res = a[slicex]; for(auto &row: res) { - row = valarray(row[slicey]); + row = std::valarray(row[slicey]); } return res; } @@ -157,7 +163,7 @@ namespace algebra { // matrix return res; } - optional inv() const { + std::optional inv() const { assert(n == m); matrix b = *this | eye(n); if(size(b.gauss(n)[0]) < n) { @@ -166,11 +172,11 @@ namespace algebra { // matrix for(size_t i = 0; i < n; i++) { b[i] *= b[i][i].inv(); } - return b.submatrix(slice(0, n, 1), slice(n, n, 1)); + return b.submatrix(std::slice(0, n, 1), std::slice(n, n, 1)); } // [solution, basis], transposed - optional> solve(matrix t) const { + std::optional> solve(matrix t) const { assert(n == t.n); matrix b = *this | t; auto [pivots, free] = b.gauss(); @@ -188,9 +194,10 @@ namespace algebra { // matrix sols[i][free[i]] = -1; } return array{ - sols.submatrix(slice(size(free) - t.m, t.m, 1), slice(0, m, 1)), - sols.submatrix(slice(0, size(free) - t.m, 1), slice(0, m, 1)) + sols.submatrix(std::slice(size(free) - t.m, t.m, 1), std::slice(0, m, 1)), + sols.submatrix(std::slice(0, size(free) - t.m, 1), std::slice(0, m, 1)) }; } }; } +#endif // ALGEBRA_MATRIX_HPP \ No newline at end of file diff --git a/src/algebra/modular.cpp b/cp-algo/algebra/modular.hpp similarity index 88% rename from src/algebra/modular.cpp rename to cp-algo/algebra/modular.hpp index 79682be..0163f6a 100644 --- a/src/algebra/modular.cpp +++ b/cp-algo/algebra/modular.hpp @@ -1,10 +1,15 @@ -namespace algebra { // modular +#ifndef ALGEBRA_MODULAR_HPP +#define ALGEBRA_MODULAR_HPP +#include "common.hpp" +#include +#include +namespace algebra { template struct modular { // https://en.wikipedia.org/wiki/Berlekamp-Rabin_algorithm // solves x^2 = y (mod m) assuming m is prime in O(log m). // returns nullopt if no sol. - optional sqrt() const { + std::optional sqrt() const { static modular y; y = *this; if(r == 0) { @@ -61,12 +66,13 @@ namespace algebra { // modular }; template - istream& operator >> (istream &in, modular &x) { + std::istream& operator >> (std::istream &in, modular &x) { return in >> x.r; } template - ostream& operator << (ostream &out, modular const& x) { + std::ostream& operator << (std::ostream &out, modular const& x) { return out << x.r % m; } } +#endif // ALGEBRA_MODULAR_HPP \ No newline at end of file diff --git a/src/algebra/polynomial.cpp b/cp-algo/algebra/polynomial.hpp similarity index 91% rename from src/algebra/polynomial.cpp rename to cp-algo/algebra/polynomial.hpp index 8745c1a..22e6dcc 100644 --- a/src/algebra/polynomial.cpp +++ b/cp-algo/algebra/polynomial.hpp @@ -1,7 +1,14 @@ -namespace algebra { // poly +#ifndef ALGEBRA_POLYNOMIAL_HPP +#define ALGEBRA_POLYNOMIAL_HPP +#include "common.hpp" +#include "modular.hpp" +#include "fft.hpp" +#include +#include +namespace algebra { template struct poly { - vector a; + std::vector a; void normalize() { // get rid of leading zeroes while(!a.empty() && a.back() == T(0)) { @@ -11,7 +18,7 @@ namespace algebra { // poly poly(){} poly(T a0) : a{a0}{normalize();} - poly(const vector &t) : a(t){normalize();} + poly(const std::vector &t) : a(t){normalize();} poly operator -() const { auto t = *this; @@ -42,7 +49,7 @@ namespace algebra { // poly poly operator - (const poly &t) const {return poly(*this) -= t;} poly mod_xk(size_t k) const { // get first k coefficients - return vector(begin(a), begin(a) + min(k, a.size())); + return std::vector(begin(a), begin(a) + min(k, a.size())); } poly mul_xk(size_t k) const { // multiply by x^k @@ -52,11 +59,11 @@ namespace algebra { // poly } poly div_xk(size_t k) const { // drop first k coefficients - return vector(begin(a) + min(k, a.size()), end(a)); + return std::vector(begin(a) + min(k, a.size()), end(a)); } poly substr(size_t l, size_t r) const { // return mod_xk(r).div_xk(l) - return vector( + return std::vector( begin(a) + min(l, a.size()), begin(a) + min(r, a.size()) ); @@ -68,7 +75,7 @@ namespace algebra { // poly poly reverse(size_t n) const { // computes x^n A(x^{-1}) auto res = a; res.resize(max(n, res.size())); - return vector(res.rbegin(), res.rbegin() + n); + return std::vector(res.rbegin(), res.rbegin() + n); } poly reverse() const { @@ -76,8 +83,8 @@ namespace algebra { // poly } pair divmod_slow(const poly &b) const { // when divisor or quotient is small - vector A(a); - vector res; + std::vector A(a); + std::vector res; T b_lead_inv = b.a.back().inv(); while(A.size() >= b.a.size()) { res.push_back(A.back() * b_lead_inv); @@ -140,7 +147,7 @@ namespace algebra { // poly }; template - static void concat(vector &a, vector const& b) { + static void concat(std::vector &a, std::vector const& b) { for(auto it: b) { a.push_back(it); } @@ -148,7 +155,7 @@ namespace algebra { // poly // finds a transform that changes A/B to A'/B' such that // deg B' is at least 2 times less than deg A - static pair, transform> half_gcd(poly A, poly B) { + static pair, transform> half_gcd(poly A, poly B) { assert(A.deg() >= B.deg()); int m = (A.deg() + 1) / 2; if(B.deg() < m) { @@ -169,9 +176,9 @@ namespace algebra { // poly } // return a transform that reduces A / B to gcd(A, B) / 0 - static pair, transform> full_gcd(poly A, poly B) { - vector ak; - vector trs; + static pair, transform> full_gcd(poly A, poly B) { + std::vector ak; + std::vector trs; while(!B.is_zero()) { if(2 * B.deg() > A.deg()) { auto [a, Tr] = half_gcd(A, B); @@ -199,6 +206,7 @@ namespace algebra { // poly } auto [a, Tr] = full_gcd(A, B); return Tr.d * A - Tr.b * B; + } // Returns the characteristic polynomial @@ -261,7 +269,7 @@ namespace algebra { // poly // calculate inv to *this modulo t // quadratic complexity - optional inv_mod_slow(poly const& t) const { + std::optional inv_mod_slow(poly const& t) const { auto R1 = *this, R2 = t; auto Q1 = poly(T(1)), Q2 = poly(T(0)); int k = 0; @@ -278,7 +286,7 @@ namespace algebra { // poly } } - optional inv_mod(poly const &t) const { + std::optional inv_mod(poly const &t) const { assert(!t.is_zero()); if(false && min(deg(), t.deg()) < magic) { return inv_mod_slow(t); @@ -365,7 +373,7 @@ namespace algebra { // poly if(deg() + 1 < k) { return poly(T(0)); } - vector res(deg() + 1 - k); + std::vector res(deg() + 1 - k); for(int i = k; i <= deg(); i++) { res[i - k] = fact(i) * rfact(i - k) * a[i]; } @@ -373,7 +381,7 @@ namespace algebra { // poly } poly integr() { // calculate integral with C = 0 - vector res(deg() + 2); + std::vector res(deg() + 2); for(int i = 0; i <= deg(); i++) { res[i + 1] = a[i] * small_inv(i + 1); } @@ -486,7 +494,7 @@ namespace algebra { // poly return poly(T(0)); } assert((*this)[0] != T(0)); - vector Q(n); + std::vector Q(n); Q[0] = bpow(a[0], k); auto a0inv = a[0].inv(); for(int i = 1; i < (int)n; i++) { @@ -520,7 +528,7 @@ namespace algebra { // poly } // returns nullopt if undefined - optional sqrt(size_t n) const { + std::optional sqrt(size_t n) const { if(is_zero()) { return *this; } @@ -569,10 +577,10 @@ namespace algebra { // poly // requires multiplying polynomials of size deg() and n+deg()! poly chirpz(T z, int n) const { // P(1), P(z), P(z^2), ..., P(z^(n-1)) if(is_zero()) { - return vector(n, 0); + return std::vector(n, 0); } if(z == T(0)) { - vector ans(n, (*this)[0]); + std::vector ans(n, (*this)[0]); if(n > 0) { ans[0] = accumulate(begin(a), end(a), T(0)); } @@ -585,7 +593,7 @@ namespace algebra { // poly // res[i] = prod_{1 <= j <= i} 1/(1 - z^j) static auto _1mzk_prod_inv(T z, int n) { - vector res(n, 1), zk(n); + std::vector res(n, 1), zk(n); zk[0] = 1; for(int i = 1; i < n; i++) { zk[i] = zk[i - 1] * z; @@ -601,12 +609,12 @@ namespace algebra { // poly // prod_{0 <= j < n} (1 - z^j x) static auto _1mzkx_prod(T z, int n) { if(n == 1) { - return poly(vector{1, -1}); + return poly(std::vector{1, -1}); } else { auto t = _1mzkx_prod(z, n / 2); t *= t.mulx(bpow(z, n / 2)); if(n % 2) { - t *= poly(vector{1, -bpow(z, n - 1)}); + t *= poly(std::vector{1, -bpow(z, n - 1)}); } return t; } @@ -620,10 +628,10 @@ namespace algebra { // poly if(n == 1) { return *this; } else { - return vector{(*this)[1], (*this)[0] - (*this)[1]}; + return std::vector{(*this)[1], (*this)[0] - (*this)[1]}; } } - vector y(n); + std::vector y(n); for(int i = 0; i < n; i++) { y[i] = (*this)[i]; } @@ -643,16 +651,16 @@ namespace algebra { // poly return (p_over_q * q).mod_xk(n).reverse(n); } - static poly build(vector &res, int v, auto L, auto R) { // builds evaluation tree for (x-a1)(x-a2)...(x-an) + static poly build(std::vector &res, int v, auto L, auto R) { // builds evaluation tree for (x-a1)(x-a2)...(x-an) if(R - L == 1) { - return res[v] = vector{-*L, 1}; + return res[v] = std::vector{-*L, 1}; } else { auto M = L + (R - L) / 2; return res[v] = build(res, 2 * v, L, M) * build(res, 2 * v + 1, M, R); } } - poly to_newton(vector &tree, int v, auto l, auto r) { + poly to_newton(std::vector &tree, int v, auto l, auto r) { if(r - l == 1) { return *this; } else { @@ -663,17 +671,17 @@ namespace algebra { // poly } } - poly to_newton(vector p) { + poly to_newton(std::vector p) { if(is_zero()) { return *this; } int n = p.size(); - vector tree(4 * n); + std::vector tree(4 * n); build(tree, 1, begin(p), end(p)); return to_newton(tree, 1, begin(p), end(p)); } - vector eval(vector &tree, int v, auto l, auto r) { // auxiliary evaluation function + std::vector eval(std::vector &tree, int v, auto l, auto r) { // auxiliary evaluation function if(r - l == 1) { return {eval(*l)}; } else { @@ -685,17 +693,17 @@ namespace algebra { // poly } } - vector eval(vector x) { // evaluate polynomial in (x1, ..., xn) + std::vector eval(std::vector x) { // evaluate polynomial in (x1, ..., xn) int n = x.size(); if(is_zero()) { - return vector(n, T(0)); + return std::vector(n, T(0)); } - vector tree(4 * n); + std::vector tree(4 * n); build(tree, 1, begin(x), end(x)); return eval(tree, 1, begin(x), end(x)); } - poly inter(vector &tree, int v, auto ly, auto ry) { // auxiliary interpolation function + poly inter(std::vector &tree, int v, auto ly, auto ry) { // auxiliary interpolation function if(ry - ly == 1) { return {*ly / a[0]}; } else { @@ -706,9 +714,9 @@ namespace algebra { // poly } } - static auto inter(vector x, vector y) { // interpolates minimum polynomial from (xi, yi) pairs + static auto inter(std::vector x, std::vector y) { // interpolates minimum polynomial from (xi, yi) pairs int n = x.size(); - vector tree(4 * n); + std::vector tree(4 * n); return build(tree, 1, begin(x), end(x)).deriv().inter(tree, 1, begin(y), end(y)); } @@ -732,7 +740,7 @@ namespace algebra { // poly } static poly ones(size_t n) { // P(x) = 1 + x + ... + x^{n-1} - return vector(n, 1); + return std::vector(n, 1); } static poly expx(size_t n) { // P(x) = e^x (mod x^n) @@ -740,7 +748,7 @@ namespace algebra { // poly } static poly log1px(size_t n) { // P(x) = log(1+x) (mod x^n) - vector coeffs(n, 0); + std::vector coeffs(n, 0); for(size_t i = 1; i < n; i++) { coeffs[i] = (i & 1 ? T(i).inv() : -T(i).inv()); } @@ -782,7 +790,7 @@ namespace algebra { // poly } poly x2() { // P(x) -> P(x^2) - vector res(2 * a.size()); + std::vector res(2 * a.size()); for(size_t i = 0; i < a.size(); i++) { res[2 * i] = a[i]; } @@ -791,7 +799,7 @@ namespace algebra { // poly // Return {P0, P1}, where P(x) = P0(x) + xP1(x) pair bisect() const { - vector res[2]; + std::vector res[2]; res[0].reserve(deg() / 2 + 1); res[1].reserve(deg() / 2 + 1); for(int i = 0; i <= deg(); i++) { @@ -850,7 +858,7 @@ namespace algebra { // poly // compute A(B(x)) mod x^n in O(n^2) static poly compose(poly A, poly B, int n) { int q = std::sqrt(n); - vector Bk(q); + std::vector Bk(q); auto Bq = B.pow(q, n); Bk[0] = poly(T(1)); for(int i = 1; i < q; i++) { @@ -881,7 +889,7 @@ namespace algebra { // poly auto [B0, B1] = make_pair(B.mod_xk(q), B.div_xk(q)); B0 = B0.div_xk(1); - vector pw(A.deg() + 1); + std::vector pw(A.deg() + 1); auto getpow = [&](int k) { return pw[k].is_zero() ? pw[k] = B0.pow(k, n - k) : pw[k]; }; @@ -904,7 +912,7 @@ namespace algebra { // poly poly ans = T(0); - vector B1p(r + 1); + std::vector B1p(r + 1); B1p[0] = poly(T(1)); for(int i = 1; i <= r; i++) { B1p[i] = (B1p[i - 1] * B1.mod_xk(n - i * q)).mod_xk(n - i * q); @@ -925,3 +933,4 @@ namespace algebra { // poly return b * a; } }; +#endif // ALGEBRA_POLYNOMIAL_HPP \ No newline at end of file diff --git a/src/data_structures/segment_tree.cpp b/cp-algo/data_structures/segment_tree.hpp similarity index 91% rename from src/data_structures/segment_tree.cpp rename to cp-algo/data_structures/segment_tree.hpp index cd83635..8a1fca6 100644 --- a/src/data_structures/segment_tree.cpp +++ b/cp-algo/data_structures/segment_tree.hpp @@ -1,3 +1,6 @@ +#ifndef DATA_STRUCTURES_SEGMENT_TREE_HPP +#define DATA_STRUCTURES_SEGMENT_TREE_HPP +#include /* Metas examples: Range Affine Range Sum, 1138ms - https://judge.yosupo.jp/submission/148324 Range Chmin Chmax Add Range Sum, 787ms - https://judge.yosupo.jp/submission/148544 @@ -7,11 +10,11 @@ namespace data_structures { template struct segment_tree { const int N; - vector _meta; + std::vector _meta; segment_tree(int n): N(n), _meta(4 * N) {} - segment_tree(vector leafs): N(size(leafs)), _meta(4 * N) { + segment_tree(std::vector leafs): N(size(leafs)), _meta(4 * N) { build(leafs); } @@ -82,3 +85,4 @@ namespace data_structures { } } } +#endif // DATA_STRUCTURES_SEGMENT_TREE_HPP \ No newline at end of file diff --git a/src/data_structures/treap.cpp b/cp-algo/data_structures/treap.hpp similarity index 95% rename from src/data_structures/treap.cpp rename to cp-algo/data_structures/treap.hpp index 1a826c8..b79cb9f 100644 --- a/src/data_structures/treap.cpp +++ b/cp-algo/data_structures/treap.hpp @@ -1,11 +1,15 @@ +#ifndef DATA_STRUCTURES_TREAP_HPP +#define DATA_STRUCTURES_TREAP_HPP +#include +#include /* Submissions on Library Judge: Range Reverse Range Sum, 558ms - https://judge.yosupo.jp/submission/147860 Cartesian Tree, 229ms - https://judge.yosupo.jp/submission/147858 Dynamic Sequence Range Affine Range Sum, 2245ms - https://judge.yosupo.jp/submission/148948 - */ +*/ namespace data_structures { namespace treap { - mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); + std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count()); #define safe(t, op) (t ? t->op : typename remove_referenceop)>::type()) template struct treap_node { @@ -134,3 +138,4 @@ namespace data_structures { }; } } +#endif // DATA_STRUCTURES_TREAP_HPP \ No newline at end of file