This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub ebi-fly13/Library
#define PROBLEM "https://judge.yosupo.jp/problem/set_xor_min" #include <iostream> #include "../../data_structure/binary_trie.hpp" int main() { int q; std::cin >> q; ebi::binary_trie<int> trie; while (q--) { int t, x; std::cin >> t >> x; if (t == 0) { if (!trie.find(x)) trie.insert(x); } else if (t == 1) { if (trie.find(x)) trie.erase(x); } else { std::cout << trie.min_element(x) << '\n'; } } }
#line 1 "test/data_structure/Set_Xor_Min.test.cpp" #define PROBLEM "https://judge.yosupo.jp/problem/set_xor_min" #include <iostream> #line 2 "data_structure/binary_trie.hpp" /* reference: https://kazuma8128.hatenablog.com/entry/2018/05/06/022654 */ #include <algorithm> #include <array> #include <cassert> #include <climits> #include <memory> namespace ebi { template <class T> struct binary_trie { private: struct Node; using node_ptr = std::shared_ptr<Node>; struct Node { int count = 0; std::array<node_ptr, 2> childs; Node() = default; }; public: binary_trie() = default; void insert(const T x) { node_ptr now = root; now->count++; for (int i = bit_size - 1; i >= 0; i--) { int index = (x >> i) & 1; if (now->childs[index] == nullptr) { now->childs[index] = std::make_shared<Node>(); } now = now->childs[index]; now->count++; } return; } void erase(const T x) { if (find(x) == false) return; node_ptr now = root; now->count--; for (int i = bit_size - 1; i >= 0; i--) { int index = (x >> i) & 1; assert(now->childs[index]); now = now->childs[index]; now->count--; } return; } bool find(const T x) const { node_ptr now = root; for (int i = bit_size - 1; i >= 0; i--) { int index = (x >> i) & 1; if (now->childs[index] == nullptr) { return false; } now = now->childs[index]; if (now->count == 0) { return false; } } return true; } T min_element(const T x) const { T val = 0; node_ptr now = root; for (int i = bit_size - 1; i >= 0; i--) { int index = ((x >> i) & 1); if (now->childs[index] && now->childs[index]->count > 0) { now = now->childs[index]; } else if (now->childs[index ^ 1] && now->childs[index ^ 1]->count > 0) { val |= T(1) << i; now = now->childs[index ^ 1]; } else { assert(0); } } return val; } T max_element(const T x) const { T val = 0; node_ptr now = root; for (int i = bit_size - 1; i >= 0; i--) { int index = ((x >> i) & 1) ^ 1; if (now->childs[index] && now->childs[index]->count > 0) { val |= T(1) << i; now = now->childs[index]; } else if (now->childs[index ^ 1] && now->childs[index ^ 1]->count > 0) { now = now->childs[index ^ 1]; } else { assert(0); } } return val; } int size() const { return root->count; } private: const size_t bit_size = sizeof(T) * CHAR_BIT; node_ptr root = std::make_shared<Node>(); }; } // namespace ebi #line 6 "test/data_structure/Set_Xor_Min.test.cpp" int main() { int q; std::cin >> q; ebi::binary_trie<int> trie; while (q--) { int t, x; std::cin >> t >> x; if (t == 0) { if (!trie.find(x)) trie.insert(x); } else if (t == 1) { if (trie.find(x)) trie.erase(x); } else { std::cout << trie.min_element(x) << '\n'; } } }