Skip to content

Commit 1b9f26e

Browse files
committed
feat: added xor linear basis
1 parent 659c118 commit 1b9f26e

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

src/alfred/math/linear.hpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
#define AFMT_LINEAR
33

44
#include <algorithm>
5+
#include <array>
56
#include <cassert>
7+
#include <limits>
68
#include <vector>
79

810
template <class T>
@@ -125,4 +127,49 @@ Matrix<T> power(Matrix<T> M, long long index) {
125127
return ans;
126128
}
127129

130+
template <class T>
131+
struct XORBasis {
132+
constexpr static T mx = std::numeric_limits<T>::max();
133+
constexpr static int C = std::__lg(mx);
134+
135+
std::array<T, C> p;
136+
bool has_zero = false;
137+
// Insert x to the basis.
138+
// Returns: successfully inserted to which digit.
139+
inline int insert(T x) {
140+
if (x == 0) has_zero = true;
141+
for (int i = C - 1; i >= 0; i--) {
142+
if (!(x >> i & 1)) continue;
143+
if (p[i] == 0) {
144+
p[i] = x;
145+
return i;
146+
} else x ^= p[i];
147+
}
148+
return -1;
149+
}
150+
inline T max(T ans = 0) {
151+
for (int i = C - 1; i >= 0; i--) {
152+
ans = std::max(ans, ans ^ p[i]);
153+
}
154+
return ans;
155+
}
156+
inline T min(T ans) {
157+
for (int i = C - 1; i >= 0; i--) {
158+
ans = std::min(ans, ans ^ p[i]);
159+
}
160+
return ans;
161+
}
162+
inline T min(void) {
163+
T lst = 0;
164+
bool all_zero = true;
165+
if (has_zero) return 0;
166+
for (int i = C - 1; i >= 0; i--) {
167+
if (p[i] != 0) {
168+
all_zero = false, lst = p[i];
169+
}
170+
}
171+
return all_zero ? mx : lst;
172+
}
173+
};
174+
128175
#endif // !AFMT_LINEAR

0 commit comments

Comments
 (0)