This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub fffelix-huang/CP-stuff
#define PROBLEM "https://judge.yosupo.jp/problem/aplusb" // dummy #include <iostream> #include <vector> #include <tuple> #include <algorithm> #include <cassert> #include "../../../library/random/rng.hpp" #include "../../../library/data-structure/treap.hpp" using namespace std; using namespace felix; using S = int; S e() { return 0; } S op(S a, S b) { return a + b; } S reversal(S s) { return s; } using F = tuple<>; F id() { return {}; } S mapping(F, S s) { return s; } F composition(F, F) { return {}; } using Treap = treap<S, e, op, reversal, F, id, mapping, composition>; void check(Treap tree, vector<int> a) { tree.clear_tag(); assert(tree.size() == (int) a.size()); reverse(a.begin(), a.end()); for(auto x : tree) { assert(x == a.back()); a.pop_back(); } } void TEST() { { cerr << "Testing insert" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } sort(a.begin(), a.end()); check(tree, a);; } { cerr << "Testing insert iterator" << endl; Treap tree; tree.insert(tree.end(), 3); auto it = tree.insert(tree.end(), 5); it = tree.insert(it, 6); vector<int> a = {3, 6, 5}; check(tree, a); tree.insert(it, 10); a = {3, 10, 6, 5}; check(tree, a); } { cerr << "Testing insert k" << endl; Treap tree; vector<int> a; for(int i = 0; i < 100; i++) { int k = rng() % (i + 1); S x = rng(); tree.insert_k(k, x); a.insert(a.begin() + k, x); check(tree, a); } } { cerr << "Testing erase" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } sort(a.begin(), a.end()); tree.erase(3); a.erase(find(a.begin(), a.end(), 3)); check(tree, a); tree.erase(10); check(tree, a); tree.erase(4); a.erase(find(a.begin(), a.end(), 4)); check(tree, a); tree.erase(7); a.erase(find(a.begin(), a.end(), 7)); check(tree, a); tree.erase(8); a.erase(find(a.begin(), a.end(), 8)); check(tree, a); tree.erase(6); a.erase(find(a.begin(), a.end(), 6)); check(tree, a); assert(tree.size() == 0 && tree.empty()); } { cerr << "Testing erase iterator" << endl; Treap tree; vector<int> a; vector<Treap::iterator> iters; for(int i = 0; i < 10; i++) { S x = rng(); auto it = tree.insert(tree.end(), x); a.push_back(x); iters.push_back(it); } while(!tree.empty()) { tree.erase(iters.back()); iters.pop_back(); a.pop_back(); check(tree, a); } } { cerr << "Testing erase k" << endl; Treap tree; vector<int> a; for(int i = 0; i < 100; i++) { S x = rng(); tree.insert(tree.end(), x); a.push_back(x); } while(!tree.empty()) { int k = rng() % tree.size(); tree.erase_k(k); a.erase(a.begin() + k); check(tree, a); } } { cerr << "Testing lower_bound" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } auto it = tree.lower_bound(1); assert(*it == 3); it = tree.lower_bound(3); assert(*it == 3); it = tree.lower_bound(8); assert(*it == 8); it = tree.lower_bound(9); assert(it == tree.end()); } { cerr << "Testing upper_bound" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } auto it = tree.upper_bound(1); assert(*it == 3); it = tree.upper_bound(3); assert(*it == 4); it = tree.upper_bound(8); assert(it == tree.end()); } { cerr << "Testing find" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } sort(a.begin(), a.end()); for(int i = 0; i < 10; i++) { auto it = tree.find(i); bool X = it != tree.end(); bool Y = binary_search(a.begin(), a.end(), i); assert(X == Y); } } { cerr << "Testing reverse" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(tree.end(), x); } tree.reverse(2, 4); reverse(a.begin() + 2, a.begin() + 4); check(tree, a); tree.reverse(); reverse(a.begin(), a.end()); check(tree, a); } { cerr << "Testing merge" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(tree.end(), x); } vector<int> b = {3, 1, 4, 1, 5}; Treap tree2; for(auto x : b) { tree2.insert(tree2.end(), x); } a.insert(a.end(), b.begin(), b.end()); tree.merge(tree2); check(tree, a); } { cerr << "Testing get_index" << endl; Treap tree; for(int i = 0; i < 100; i++) { int k = rng() % (i + 1); auto it = tree.insert_k(k, (S) rng()); assert(tree.get_index(it) == k); } } { cerr << "Testing split k" << endl; Treap tree; vector<int> a; for(int i = 0; i < 100; i++) { S x = rng(); tree.insert(tree.end(), x); a.push_back(x); } int k = rng() % (tree.size() + 1); auto [t1, t2] = tree.split_k(k); vector<int> b(a.begin(), a.begin() + k); vector<int> c(a.begin() + k, a.end()); check(t1, b); check(t2, c); assert(tree.size() == 0 && tree.empty()); } { cerr << "Testing split_range" << endl; Treap tree; vector<int> a = {3, 1, 4}, b = {1, 5, 9}, c = {2, 6, 5}; for(auto v : {a, b, c}) { for(auto x : v) { tree.insert(tree.end(), x); } } auto [L, M, R] = tree.split_range(3, 6); check(L, a); check(M, b); check(R, c); assert(tree.size() == 0 && tree.empty()); } { cerr << "Testing clear" << endl; Treap tree; for(int i = 0; i < 100; i++) { tree.insert((S) rng()); } tree.clear(); assert(tree.size() == 0 && tree.empty()); } cerr << "Passed test." << endl; } int main() { TEST(); int a, b; cin >> a >> b; cout << a + b << "\n"; return 0; }
#line 1 "test/data-structure/treap/unit-test-treap.test.cpp" #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" // dummy #include <iostream> #include <vector> #include <tuple> #include <algorithm> #include <cassert> #line 2 "library/random/rng.hpp" #include <chrono> namespace felix { inline unsigned long long rng() { static unsigned long long SEED = std::chrono::steady_clock::now().time_since_epoch().count(); SEED ^= SEED << 7; SEED ^= SEED >> 9; return SEED; } } // namespace felix #line 3 "library/bst/rbst-base.hpp" #include <functional> #line 5 "library/bst/rbst-base.hpp" namespace felix { namespace internal { template<class node_t, class Comp = std::less<decltype(node_t::key)>> struct rbst_base { using key_type = decltype(node_t::key); private: static const Comp Compare; public: static node_t* merge(node_t* a, node_t* b) { if(a == nullptr || b == nullptr) { return a != nullptr ? a : b; } if((int) (((unsigned int) rng() * 1LL * (a->size + b->size)) >> 32) < a->size) { a->push(); a->r = merge(a->r, b); a->pull(); return a; } else { b->push(); b->l = merge(a, b->l); b->pull(); return b; } } static std::pair<node_t*, node_t*> split(node_t* v, int k) { if(v == nullptr) { return {nullptr, nullptr}; } v->push(); if(k <= get_size(v->l)) { auto p = split(v->l, k); v->l = p.second; if(p.first != nullptr) { p.first->p = nullptr; } v->pull(); return {p.first, v}; } else { auto p = split(v->r, k - get_size(v->l) - 1); v->r = p.first; if(p.second != nullptr) { p.second->p = nullptr; } v->pull(); return {v, p.second}; } } static std::tuple<node_t*, node_t*, node_t*> split_range(node_t* v, int l, int r) { auto p = split(v, l); auto q = split(p.second, r - l); return {p.first, q.first, q.second}; } static void insert(node_t*& v, int k, const key_type& val) { auto p = split(v, k); v = merge(p.first, merge(new node_t(val), p.second)); } static void erase(node_t*& v, int k) { auto p = split_range(v, k, k + 1); delete std::get<1>(p); v = merge(std::get<0>(p), std::get<2>(p)); } static int lower_bound(node_t* v, const key_type& val) { if(v == nullptr) { return 0; } // TTTTFFFF // ^ if(Compare(v->key, val)) { return get_size(v->l) + 1 + lower_bound(v->r, val); } else { return lower_bound(v->l, val); } } static int upper_bound(node_t* v, const key_type& val) { // 1 2 3 3 4 // ^ // F F F F T if(v == nullptr) { return 0; } if(!Compare(val, v->key)) { return get_size(v->l) + 1 + upper_bound(v->r, val); } else { return upper_bound(v->l, val); } } static key_type get(node_t*& v, int k) { auto p = split_range(v, k, k + 1); key_type res = std::get<1>(p)->key; v = merge(std::get<0>(p), merge(std::get<1>(p), std::get<2>(p))); return res; } static int get_index(node_t* v) { int k = get_size(v->l); while(v->p != nullptr) { if(v == v->p->r) { k++; if(v->p->l != nullptr) { k += v->p->l->size; } } v = v->p; } return k; } static void clear(node_t*& v) { postorder(v, [](node_t* v) { delete v; }); v = nullptr; } static node_t* next(node_t* v) { if(v->r == nullptr) { while(v->p != nullptr && v->p->r == v) { v = v->p; } return v->p; } v->push(); if(v->r == nullptr) { return nullptr; } v = v->r; while(v->l != nullptr) { v->push(); v = v->l; } return v; } static node_t* prev(node_t* v) { if(v->l == nullptr) { while(v->p != nullptr && v->p->l == v) { v = v->p; } return v->p; } v->push(); if(v->l == nullptr) { return nullptr; } v = v->l; while(v->r != nullptr) { v->push(); v = v->r; } return v; } template<class Func> static void preorder(node_t* v, const Func& f) { auto rec = [&](auto rec, node_t* v) -> void { if(v == nullptr) { return; } v->push(); f(v); rec(rec, v->l); rec(rec, v->r); }; rec(rec, v); } template<class Func> static void inorder(node_t* v, const Func& f) { auto rec = [&](auto rec, node_t* v) -> void { if(v == nullptr) { return; } v->push(); rec(rec, v->l); f(v); rec(rec, v->r); }; rec(rec, v); } template<class Func> static void postorder(node_t* v, const Func& f) { auto rec = [&](auto rec, node_t* v) -> void { if(v == nullptr) { return; } v->push(); rec(rec, v->l); rec(rec, v->r); f(v); }; rec(rec, v); } static int size(node_t* v) { return get_size(v); } static bool empty(node_t* v) { return v == nullptr; } private: static int get_size(node_t* v) { return v != nullptr ? v->size : 0; } }; template<class node_t, class Comp> const Comp rbst_base<node_t, Comp>::Compare = Comp(); } // namespace internal } // namespace felix #line 3 "library/data-structure/treap.hpp" namespace felix { namespace internal_treap { template<class S, S (*e)(), S (*op)(S, S)> struct treap_node { S key = e(), sum = e(); int size = 1; treap_node* l = nullptr; treap_node* r = nullptr; treap_node* p = nullptr; treap_node() {} treap_node(const S& s) : key(s), sum(s) {} void push() {} void pull() { size = 1; sum = key; if(l != nullptr) { size += l->size; sum = op(l->sum, sum); l->p = this; } if(r != nullptr) { size += r->size; sum = op(sum, r->sum); r->p = this; } } }; } // namespace internal_treap template<class S, S (*e)(), S (*op)(S, S), class Comp = std::less<S>> struct treap : public internal::rbst_base<internal_treap::treap_node<S, e, op>, Comp> { using node_t = internal_treap::treap_node<S, e, op>; using base = internal::rbst_base<internal_treap::treap_node<S, e, op>, Comp>; using base::split_range_by_size, base::merge; using base::root; public: treap() {} void set(int k, const S& s) { auto [lhs, mid, rhs] = split_range_by_size(k, k + 1); mid.clear(); mid.insert(mid.end(), s); merge(lhs), merge(mid), merge(rhs); } S prod(int l, int r) { if(l == r) { return e(); } auto [lhs, mid, rhs] = split_range_by_size(l, r); S ans = mid.root->sum; merge(lhs), merge(mid), merge(rhs); return ans; } S all_prod() { root->push(); return root->sum; } }; } // namespace felix #line 10 "test/data-structure/treap/unit-test-treap.test.cpp" using namespace std; using namespace felix; using S = int; S e() { return 0; } S op(S a, S b) { return a + b; } S reversal(S s) { return s; } using F = tuple<>; F id() { return {}; } S mapping(F, S s) { return s; } F composition(F, F) { return {}; } using Treap = treap<S, e, op, reversal, F, id, mapping, composition>; void check(Treap tree, vector<int> a) { tree.clear_tag(); assert(tree.size() == (int) a.size()); reverse(a.begin(), a.end()); for(auto x : tree) { assert(x == a.back()); a.pop_back(); } } void TEST() { { cerr << "Testing insert" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } sort(a.begin(), a.end()); check(tree, a);; } { cerr << "Testing insert iterator" << endl; Treap tree; tree.insert(tree.end(), 3); auto it = tree.insert(tree.end(), 5); it = tree.insert(it, 6); vector<int> a = {3, 6, 5}; check(tree, a); tree.insert(it, 10); a = {3, 10, 6, 5}; check(tree, a); } { cerr << "Testing insert k" << endl; Treap tree; vector<int> a; for(int i = 0; i < 100; i++) { int k = rng() % (i + 1); S x = rng(); tree.insert_k(k, x); a.insert(a.begin() + k, x); check(tree, a); } } { cerr << "Testing erase" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } sort(a.begin(), a.end()); tree.erase(3); a.erase(find(a.begin(), a.end(), 3)); check(tree, a); tree.erase(10); check(tree, a); tree.erase(4); a.erase(find(a.begin(), a.end(), 4)); check(tree, a); tree.erase(7); a.erase(find(a.begin(), a.end(), 7)); check(tree, a); tree.erase(8); a.erase(find(a.begin(), a.end(), 8)); check(tree, a); tree.erase(6); a.erase(find(a.begin(), a.end(), 6)); check(tree, a); assert(tree.size() == 0 && tree.empty()); } { cerr << "Testing erase iterator" << endl; Treap tree; vector<int> a; vector<Treap::iterator> iters; for(int i = 0; i < 10; i++) { S x = rng(); auto it = tree.insert(tree.end(), x); a.push_back(x); iters.push_back(it); } while(!tree.empty()) { tree.erase(iters.back()); iters.pop_back(); a.pop_back(); check(tree, a); } } { cerr << "Testing erase k" << endl; Treap tree; vector<int> a; for(int i = 0; i < 100; i++) { S x = rng(); tree.insert(tree.end(), x); a.push_back(x); } while(!tree.empty()) { int k = rng() % tree.size(); tree.erase_k(k); a.erase(a.begin() + k); check(tree, a); } } { cerr << "Testing lower_bound" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } auto it = tree.lower_bound(1); assert(*it == 3); it = tree.lower_bound(3); assert(*it == 3); it = tree.lower_bound(8); assert(*it == 8); it = tree.lower_bound(9); assert(it == tree.end()); } { cerr << "Testing upper_bound" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } auto it = tree.upper_bound(1); assert(*it == 3); it = tree.upper_bound(3); assert(*it == 4); it = tree.upper_bound(8); assert(it == tree.end()); } { cerr << "Testing find" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(x); } sort(a.begin(), a.end()); for(int i = 0; i < 10; i++) { auto it = tree.find(i); bool X = it != tree.end(); bool Y = binary_search(a.begin(), a.end(), i); assert(X == Y); } } { cerr << "Testing reverse" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(tree.end(), x); } tree.reverse(2, 4); reverse(a.begin() + 2, a.begin() + 4); check(tree, a); tree.reverse(); reverse(a.begin(), a.end()); check(tree, a); } { cerr << "Testing merge" << endl; Treap tree; vector<int> a = {4, 8, 7, 6, 3}; for(auto x : a) { tree.insert(tree.end(), x); } vector<int> b = {3, 1, 4, 1, 5}; Treap tree2; for(auto x : b) { tree2.insert(tree2.end(), x); } a.insert(a.end(), b.begin(), b.end()); tree.merge(tree2); check(tree, a); } { cerr << "Testing get_index" << endl; Treap tree; for(int i = 0; i < 100; i++) { int k = rng() % (i + 1); auto it = tree.insert_k(k, (S) rng()); assert(tree.get_index(it) == k); } } { cerr << "Testing split k" << endl; Treap tree; vector<int> a; for(int i = 0; i < 100; i++) { S x = rng(); tree.insert(tree.end(), x); a.push_back(x); } int k = rng() % (tree.size() + 1); auto [t1, t2] = tree.split_k(k); vector<int> b(a.begin(), a.begin() + k); vector<int> c(a.begin() + k, a.end()); check(t1, b); check(t2, c); assert(tree.size() == 0 && tree.empty()); } { cerr << "Testing split_range" << endl; Treap tree; vector<int> a = {3, 1, 4}, b = {1, 5, 9}, c = {2, 6, 5}; for(auto v : {a, b, c}) { for(auto x : v) { tree.insert(tree.end(), x); } } auto [L, M, R] = tree.split_range(3, 6); check(L, a); check(M, b); check(R, c); assert(tree.size() == 0 && tree.empty()); } { cerr << "Testing clear" << endl; Treap tree; for(int i = 0; i < 100; i++) { tree.insert((S) rng()); } tree.clear(); assert(tree.size() == 0 && tree.empty()); } cerr << "Passed test." << endl; } int main() { TEST(); int a, b; cin >> a >> b; cout << a + b << "\n"; return 0; }