Library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub ebi-fly13/Library

:heavy_check_mark: test/data_structure/Set_Xor_Min.test.cpp

Depends on

Code

#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';
        }
    }
}
Back to top page