Skip to content

Commit 796f68e

Browse files
committed
changes
1 parent 39a94dd commit 796f68e

File tree

3 files changed

+61
-24
lines changed

3 files changed

+61
-24
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bitset<B> walk(bitset<B>& k) {
2+
bitset<B> res;
3+
for (int i = B, j = npivot; i--;)
4+
if (basis[i][i] && res[i] ^ k[--j]) res ^= basis[i];
5+
return res;
6+
}

library/math/matrix_related/xor_basis_ordered.hpp

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,24 @@
55
//! basis_ordered<int> b1;
66
//! basis_ordered<ll> b2;
77
//! basis_ordered<bitset<lg>> b3;
8-
//! b2.insert(x); // 0 <= x < (1LL<<lg)
8+
//! b2.insert(x); // 0 <= x < (1LL<<B)
99
//! @endcode
10-
//! @time O(lg)
11-
//! @space O(lg)
12-
const int lg = 60;
13-
template<class T> struct basis_ordered {
14-
int siz = 0;
15-
T b[lg]{};
16-
int shrink(T& v) {
17-
for (int i = lg - 1; i >= 0; i--)
18-
if (((v >> i) & T(1)) != T(0)) {
19-
if (b[i] == T(0)) return i;
20-
v ^= b[i];
10+
//! @time O(q * B^2/32)
11+
//! @space O(B^2/32)
12+
template<int B> struct xor_basis {
13+
bitset<B> basis[B];
14+
int npivot = 0, nfree = 0;
15+
int shrink(bitset<B>& v) {
16+
for (int i = B; i--;)
17+
if (v[i]) {
18+
if (basis[i][i]) return i;
19+
v ^= basis[i];
2120
}
2221
return -1;
2322
}
24-
bool insert(T v) {
23+
bool insert(bitset<B>& v) {
2524
int i = shrink(v);
26-
return i >= 0 ? b[i] = v, ++siz : 0;
27-
}
28-
T walk(T k) {
29-
T res{};
30-
for (int i = lg - 1, j = siz - 1; i >= 0; i--)
31-
if (b[i] != T(0)) {
32-
if ((((res >> i) ^ (k >> j)) & T(1)) != T(0))
33-
res ^= b[i];
34-
j--;
35-
}
36-
return res;
25+
return i >= 0 ? basis[i] = v, ++npivot : !++nfree;
3726
}
27+
#include "walk.hpp"
3828
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#define PROBLEM \
2+
"https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A"
3+
#include "../template.hpp"
4+
#include "../../../library/contest/random.hpp"
5+
#include "../../../library/math/matrix_related/xor_basis_ordered.hpp"
6+
const int B = 18;
7+
vector<bitset<B>> get_all(const vector<bitset<B>>& basis) {
8+
int n = ssize(basis);
9+
vector<bitset<B>> span;
10+
for (int mask = 0; mask < (1 << n); mask++) {
11+
bitset<B> curr_xor;
12+
assert(curr_xor.none());
13+
for (int bit = 0; bit < n; bit++)
14+
if ((mask >> bit) & 1) curr_xor ^= basis[bit];
15+
span.push_back(curr_xor);
16+
}
17+
ranges::sort(span, {}, [&](const bitset<B>& x) -> long {
18+
return x.to_ulong();
19+
});
20+
return span;
21+
}
22+
int main() {
23+
cin.tie(0)->sync_with_stdio(0);
24+
for (int num_tests = 0; num_tests < 10000; num_tests++) {
25+
xor_basis<B> b;
26+
int n = rnd(1, 18);
27+
vector<bitset<B>> naive_basis;
28+
for (int i = 0; i < n; i++) {
29+
bitset<B> val = rnd(0, (1 << n) - 1);
30+
if (b.insert(val)) naive_basis.push_back(val);
31+
}
32+
vector<bitset<B>> fast_basis;
33+
for (int i = 0; i < B; i++)
34+
if (b.basis[i].any())
35+
fast_basis.push_back(b.basis[i]);
36+
vector<bitset<B>> naive_span = get_all(naive_basis);
37+
vector<bitset<B>> fast_span = get_all(fast_basis);
38+
assert(naive_span == fast_span);
39+
}
40+
cout << "Hello World\n";
41+
}

0 commit comments

Comments
 (0)