Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
binary_trie.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2
3/// @brief Binary Trie
4template<typename T=uint32_t, int Log=32>
5struct BinaryTrie {
6 BinaryTrie() { root=nullptr; }
7
8 /// @brief BinaryTrie のサイズを返す
9 int size() const {
10 if(root==nullptr) return 0;
11 return root->size;
12 }
13
14 /// @brief x を t 個挿入する
15 void insert(T x, int t=1) { root=insert(root,x,Log-1,t); }
16
17 /// @brief x を min(count(x), t) 個削除する
18 void erase(T x, int t=1) {
19 t=min(t,count(x));
20 if(t==0) return;
21 root=erase(root,x,Log-1,t);
22 }
23
24 /// @brief 要素全体に x を xor する
25 void apply_xor(T x) { if(root!=nullptr) root->lazy^=x; }
26
27 /// @brief 最大値を返す
28 T max() { return get_min(root,~0,Log-1); }
29
30 /// @brief 最小値を返す
31 T min() { return get_min(root,0,Log-1); }
32
33 /// @brief k(0-indexed) 番目に小さい要素を返す
34 T kth_min(int k) {
35 assert(0<=k&&k<size());
36 return get(root,k,Log-1);
37 }
38
39 /// @brief x 以上の最小の要素が何番目に小さいかを返す
40 int lower_bound(T x) { return count_lower(root,x,Log-1); }
41
42 /// @brief x がいくつ含まれているかを返す
43 int count(T x) {
44 if(root==nullptr)return 0;
45 Node*v=root;
46 for(int i=Log-1; i>=0; i--) {
47 evaluate(v,i);
48 v=v->next[(x>>i)&1];
49 if(v==nullptr)return 0;
50 }
51 return v->size;
52 }
53
54private:
55 struct Node {
56 Node*next[2];
57 int size;
58 T lazy;
59 Node() {
60 size=0;
61 lazy=0;
62 next[0]=next[1]=nullptr;
63 }
64 };
65
66 Node*root;
67
68 void evaluate(Node*v, int bit) {
69 if((v->lazy>>bit)&1) swap(v->next[0],v->next[1]);
70 if(v->next[0]!=nullptr) v->next[0]->lazy^=v->lazy;
71 if(v->next[1]!=nullptr) v->next[1]->lazy^=v->lazy;
72 v->lazy=0;
73 }
74
75 Node*insert(Node*v, T x, int bit, int cnt) {
76 if(v==nullptr) v=new Node;
77 v->size+=cnt;
78 if(bit<0) return v;
79 evaluate(v,bit);
80 int lr=(x>>bit)&1;
81 v->next[lr]=insert(v->next[lr],x,bit-1,cnt);
82 return v;
83 }
84
85 Node*erase(Node*v, T x, int bit, int cnt) {
86 assert(v!=nullptr);
87 v->size-=cnt;
88 if(v->size==0) return nullptr;
89 if(bit<0) return v;
90 evaluate(v,bit);
91 int lr=(x>>bit)&1;
92 v->next[lr]=erase(v->next[lr],x,bit-1,cnt);
93 return v;
94 }
95
96 T get_min(Node*v, T x, int bit) {
97 if(bit<0) return 0;
98 evaluate(v,bit);
99 int lr=(x>>bit)&1;
100 if(v->next[lr]==nullptr) lr=1-lr;
101 return get_min(v->next[lr],x,bit-1)|((T)lr<<bit);
102 }
103
104 T get(Node*v, int k, int bit) {
105 if(bit<0) return 0;
106 evaluate(v,bit);
107 int m=(v->next[0]!=nullptr ? v->next[0]->size : 0);
108 if(k<m) return get(v->next[0],k,bit-1);
109 else return get(v->next[1],k-m,bit-1)|((T)1<<bit);
110 }
111
112 int count_lower(Node*v,T x,int bit) {
113 if(v==nullptr||bit<0) return 0;
114 evaluate(v,bit);
115 int lr=(x>>bit)&1;
116 int ret=(lr&&v->next[0]!=nullptr ? v->next[0]->size : 0);
117 return ret+count_lower(v->next[lr],x,bit-1);
118 }
119};
Binary Trie
void apply_xor(T x)
要素全体に x を xor する
T kth_min(int k)
k(0-indexed) 番目に小さい要素を返す
T max()
最大値を返す
void insert(T x, int t=1)
x を t 個挿入する
int count(T x)
x がいくつ含まれているかを返す
int size() const
BinaryTrie のサイズを返す
int lower_bound(T x)
x 以上の最小の要素が何番目に小さいかを返す
T min()
最小値を返す
void erase(T x, int t=1)
x を min(count(x), t) 個削除する