$\newcommand{\O}{\mathrm{O}}$
Binary Trie(トライ)木とよばれる木構造を構築するアルゴリズム.
Trie(トライ)木の子を2つに限定したようなデータ構造で数字の $2$ 進数表現を上手く管理するときに使う(同様のアルゴリズム).
数字の xor についての問題は各数字をビットごとに見ると上手くいくことが多く,その際にこのデータ構造が使える印象がある.
時間計算量: 構築, クエリ $\O (L)$ ($L$ = 挿入する数の総ビット長)
class BinaryTrie { public: struct Node { Node *next[2]; int sub; Node() : sub(0) { next[0] = next[1] = nullptr; } }; Node* root; //2^30より小さい場合 const int MAX_BIT = 30; BinaryTrie(){ root = new Node(); } //Trie木にxを加える void add(int x) { Node *curr = root; for(int i = MAX_BIT-1; i >= 0; i--){ int y = x >> i & 1; if (!curr->next[y]) { curr->next[y] = new Node(); } curr->sub++; curr = curr->next[y]; } curr->sub++; } //何らかのクエリ int query(Node *curr,const int a,int d){ if(!curr) return 0; if((a >> d) & 1){ return query(curr->next[1],a,d-1); }else{ return query(curr->next[0],a,d-1); } } int query(const int a){ return query(root,a,MAX_BIT-1); } };
Atcoder : Prefix-free Game 提出コード