-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathxor_gauss.cpp
46 lines (46 loc) · 1.15 KB
/
xor_gauss.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const int L = 60;
struct Basis {
ll B[L], R, last_bit;
Basis() { memset(B, 0, sizeof B), R = 0; }
ll reduce(ll x) {
for (int i = L - 1; i >= 0; i--) {
if ((x >> i) & 1) {
if (B[i] != 0) {
x ^= B[i];
} else {
last_bit = i;
return x;
}
}
}
// assert(x == 0);
return 0;
}
bool insert(ll x) {
x = reduce(x);
if (x > 0) {
R++;
B[last_bit] = x;
return true;
}
return false;
}
ll kth_smallest(ll k) {
ll ans = 0;
ll half = 1LL << (R - 1);
for (int i = L - 1; i >= 0; i--) {
if (B[i] != 0) {
if ((ans >> i) & 1) {
if (k > half) k -= half;
else ans ^= B[i];
} else if (k > half) {
ans ^= B[i];
k -= half;
}
half >>= 1;
}
}
return ans;
}
ll kth_greatest(ll k) { return kth_smallest((1LL << R) - k + 1); }
};