Skip to content

Commit cd1a3f0

Browse files
committed
Fix F2 bitset linalg
1 parent 36e565a commit cd1a3f0

File tree

5 files changed

+56
-13
lines changed

5 files changed

+56
-13
lines changed

linear_algebra_matrix/linalg_bitset.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// Complexity: O(nm + nm rank(M) / 64)
1010
// Verified: abc276_h (2000 x 8000)
1111
template <int Wmax>
12-
std::vector<std::bitset<Wmax>> gauss_jordan(int W, std::vector<std::bitset<Wmax>> M) {
12+
std::vector<std::bitset<Wmax>> f2_gauss_jordan(int W, std::vector<std::bitset<Wmax>> M) {
1313
assert(W <= Wmax);
1414
int H = M.size(), c = 0;
1515
for (int h = 0; h < H and c < W; ++h, ++c) {
@@ -33,7 +33,7 @@ std::vector<std::bitset<Wmax>> gauss_jordan(int W, std::vector<std::bitset<Wmax>
3333
}
3434

3535
// Rank of Gauss-Jordan eliminated matrix
36-
template <int Wmax> int rank_gauss_jordan(int W, const std::vector<std::bitset<Wmax>> &M) {
36+
template <int Wmax> int f2_rank_gauss_jordan(int W, const std::vector<std::bitset<Wmax>> &M) {
3737
assert(W <= Wmax);
3838
for (int h = (int)M.size() - 1; h >= 0; h--) {
3939
int j = 0;
@@ -72,25 +72,25 @@ template <int Wmax> int f2_determinant(const std::vector<std::bitset<Wmax>> &M)
7272

7373
template <int W1, int W2>
7474
std::vector<std::bitset<W2>>
75-
matmul(const std::vector<std::bitset<W1>> &A, const std::vector<std::bitset<W2>> &B) {
75+
f2_matmul(const std::vector<std::bitset<W1>> &A, const std::vector<std::bitset<W2>> &B) {
7676
int H = A.size(), K = B.size();
7777
std::vector<std::bitset<W2>> C(H);
7878
for (int i = 0; i < H; i++) {
7979
for (int j = 0; j < K; j++) {
80-
if (A[i][j]) C[i] ^= B[j];
80+
if (A.at(i).test(j)) C.at(i) ^= B.at(j);
8181
}
8282
}
8383
return C;
8484
}
8585

8686
template <int Wmax>
87-
std::vector<std::bitset<Wmax>> matpower(std::vector<std::bitset<Wmax>> X, long long n) {
87+
std::vector<std::bitset<Wmax>> f2_matpower(std::vector<std::bitset<Wmax>> X, long long n) {
8888
int D = X.size();
8989
std::vector<std::bitset<Wmax>> ret(D);
9090
for (int i = 0; i < D; i++) ret[i][i] = 1;
9191
while (n) {
92-
if (n & 1) ret = matmul<Wmax, Wmax>(ret, X);
93-
X = matmul<Wmax, Wmax>(X, X), n >>= 1;
92+
if (n & 1) ret = f2_matmul<Wmax, Wmax>(ret, X);
93+
X = f2_matmul<Wmax, Wmax>(X, X), n >>= 1;
9494
}
9595
return ret;
9696
}
@@ -101,7 +101,7 @@ std::vector<std::bitset<Wmax>> matpower(std::vector<std::bitset<Wmax>> X, long l
101101
// Complexity: O(HW + HW rank(A) / 64 + W^2 len(freedoms))
102102
template <int Wmax, class Vec>
103103
std::tuple<bool, std::bitset<Wmax>, std::vector<std::bitset<Wmax>>>
104-
system_of_linear_equations(std::vector<std::bitset<Wmax>> A, Vec b, int W) {
104+
f2_system_of_linear_equations(std::vector<std::bitset<Wmax>> A, Vec b, int W) {
105105
int H = A.size();
106106
assert(W <= Wmax);
107107
assert(A.size() == b.size());
@@ -111,7 +111,7 @@ system_of_linear_equations(std::vector<std::bitset<Wmax>> A, Vec b, int W) {
111111
for (int j = 0; j < W; ++j) M[i][j] = A[i][j];
112112
M[i][W] = b[i];
113113
}
114-
M = gauss_jordan<Wmax + 1>(W + 1, M);
114+
M = f2_gauss_jordan<Wmax + 1>(W + 1, M);
115115
std::vector<int> ss(W, -1);
116116
std::vector<int> ss_nonneg_js;
117117
for (int i = 0; i < H; i++) {

linear_algebra_matrix/linalg_bitset.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ vector<bitset<Wmax>> A;
1515
vector<bool> b;
1616

1717
// Solve Ax = b (x: F_2^W)
18-
auto [feasible, x0, freedoms] = system_of_linear_equations<Wmax, vector<bool>>(A, b, W);
18+
auto [feasible, x0, freedoms] = f2_system_of_linear_equations<Wmax, vector<bool>>(A, b, W);
1919

2020
// Calc determinant (or check whether A is regular)
2121
int det = f2_determinant<dim>(mat);

linear_algebra_matrix/test/linalg_bitset.test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ int main() {
2626
}
2727

2828
cin >> T;
29-
A = matpower<Wmax>(A, T);
29+
A = f2_matpower<Wmax>(A, T);
3030
for (int i = 0; i < N; i++) A[i][N] = v[i];
31-
A = gauss_jordan<Wmax>(N + 1, A);
31+
A = f2_gauss_jordan<Wmax>(N + 1, A);
3232

3333
for (int i = 0; i < N; i++) {
3434
if (A[i].count() == 1 and A[i][N]) {

linear_algebra_matrix/test/linalg_bitset.yuki1421.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ int main() {
5959
}
6060
A.emplace_back(a);
6161
}
62-
auto [ok, solution, freedoms] = system_of_linear_equations<Wmax, vector<bool>>(A, b, N);
62+
auto [ok, solution, freedoms] = f2_system_of_linear_equations<Wmax, vector<bool>>(A, b, N);
6363
if (!ok) bad();
6464
for (int i = 0; i < N; ++i) ret[i] += int(solution[i]) << d;
6565
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/matrix_product_mod_2"
2+
#include "../linalg_bitset.hpp"
3+
4+
#include <algorithm>
5+
#include <bitset>
6+
#include <iostream>
7+
#include <string>
8+
#include <vector>
9+
using namespace std;
10+
11+
int main() {
12+
cin.tie(nullptr);
13+
ios::sync_with_stdio(false);
14+
15+
constexpr int dim = 1 << 12;
16+
17+
using BS = bitset<dim>;
18+
19+
int N, M, K;
20+
cin >> N >> M >> K;
21+
22+
vector<BS> A(N), B(M);
23+
for (auto &v : A) {
24+
string s;
25+
cin >> s;
26+
std::reverse(s.begin(), s.end()); // bitset に文字列 s を与えると s[0] が最高位になるので反転
27+
v = BS(s);
28+
}
29+
30+
for (auto &v : B) {
31+
string s;
32+
cin >> s;
33+
std::reverse(s.begin(), s.end());
34+
v = BS(s);
35+
}
36+
37+
auto C = f2_matmul<dim, dim>(A, B);
38+
for (const auto &v : C) {
39+
auto tmp = v.to_string();
40+
std::reverse(tmp.begin(), tmp.end());
41+
cout << tmp.substr(0, K) << '\n';
42+
}
43+
}

0 commit comments

Comments
 (0)