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) {
16 root=insert(root,x,Log-1,t);
17 }
18
19 /// @brief x を min(count(x), t) 個削除する
20 void erase(T x, int t=1) {
21 t=min(t,count(x));
22 if(t==0) return;
23 root=erase(root,x,Log-1,t);
24 }
25
26 /// @brief 要素全体に x を xor する
27 void apply_xor(T x) {
28 if(root!=nullptr) root->lazy^=x;
29 }
30
31 /// @brief 最大値を返す
32 T max() {
33 return get_min(root,~0,Log-1);
34 }
35
36 /// @brief 最小値を返す
37 T min() {
38 return get_min(root,0,Log-1);
39 }
40
41 /// @brief k(0-indexed) 番目に小さい要素を返す
42 T kth_min(int k) {
43 assert(0<=k&&k<size());
44 return get(root,k,Log-1);
45 }
46
47 /// @brief x 以上の最小の要素が何番目に小さいかを返す
48 int lower_bound(T x) {
49 return count_lower(root,x,Log-1);
50 }
51
52 /// @brief x がいくつ含まれているかを返す
53 int count(T x) {
54 if(root==nullptr)return 0;
55 Node*v=root;
56 for(int i=Log-1; i>=0; i--) {
57 evaluate(v,i);
58 v=v->next[(x>>i)&1];
59 if(v==nullptr)return 0;
60 }
61 return v->size;
62 }
63
64private:
65 struct Node {
66 Node*next[2];
67 int size;
68 T lazy;
69 Node() {
70 size=0;
71 lazy=0;
72 next[0]=next[1]=nullptr;
73 }
74 };
75
76 Node*root;
77
78 void evaluate(Node*v, int bit) {
79 if((v->lazy>>bit)&1) swap(v->next[0],v->next[1]);
80 if(v->next[0]!=nullptr) v->next[0]->lazy^=v->lazy;
81 if(v->next[1]!=nullptr) v->next[1]->lazy^=v->lazy;
82 v->lazy=0;
83 }
84
85 Node*insert(Node*v, T x, int bit, int cnt) {
86 if(v==nullptr) v=new Node;
87 v->size+=cnt;
88 if(bit<0) return v;
89 evaluate(v,bit);
90 int lr=(x>>bit)&1;
91 v->next[lr]=insert(v->next[lr],x,bit-1,cnt);
92 return v;
93 }
94
95 Node*erase(Node*v, T x, int bit, int cnt) {
96 assert(v!=nullptr);
97 v->size-=cnt;
98 if(v->size==0) return nullptr;
99 if(bit<0) return v;
100 evaluate(v,bit);
101 int lr=(x>>bit)&1;
102 v->next[lr]=erase(v->next[lr],x,bit-1,cnt);
103 return v;
104 }
105
106 T get_min(Node*v, T x, int bit) {
107 if(bit<0) return 0;
108 evaluate(v,bit);
109 int lr=(x>>bit)&1;
110 if(v->next[lr]==nullptr) lr=1-lr;
111 return get_min(v->next[lr],x,bit-1)|((T)lr<<bit);
112 }
113
114 T get(Node*v, int k, int bit) {
115 if(bit<0) return 0;
116 evaluate(v,bit);
117 int m=(v->next[0]!=nullptr ? v->next[0]->size : 0);
118 if(k<m) return get(v->next[0],k,bit-1);
119 else return get(v->next[1],k-m,bit-1)|((T)1<<bit);
120 }
121
122 int count_lower(Node*v,T x,int bit) {
123 if(v==nullptr||bit<0) return 0;
124 evaluate(v,bit);
125 int lr=(x>>bit)&1;
126 int ret=(lr&&v->next[0]!=nullptr ? v->next[0]->size : 0);
127 return ret+count_lower(v->next[lr],x,bit-1);
128 }
129};
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) 個削除する