99// Complexity: O(nm + nm rank(M) / 64)
1010// Verified: abc276_h (2000 x 8000)
1111template <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 ;
@@ -43,27 +43,54 @@ template <int Wmax> int rank_gauss_jordan(int W, const std::vector<std::bitset<W
4343 return 0 ;
4444}
4545
46+ // determinant of F2 matrix.
47+ // Return 0 if the matrix is singular, otherwise return 1.
48+ // Complexity: O(W^3 / 64)
49+ template <int Wmax> int f2_determinant (const std::vector<std::bitset<Wmax>> &M) {
50+ const int H = M.size ();
51+ if (H > Wmax) return 0 ;
52+
53+ auto tmp = M;
54+ for (int h = 0 ; h < H; ++h) {
55+ int piv = -1 ;
56+ for (int j = h; j < H; ++j) {
57+ if (tmp.at (j).test (h)) {
58+ piv = j;
59+ break ;
60+ }
61+ }
62+ if (piv == -1 ) return 0 ; // singular
63+
64+ if (piv != h) std::swap (tmp.at (piv), tmp.at (h));
65+ for (int hh = h + 1 ; hh < H; ++hh) {
66+ if (tmp.at (hh).test (h)) tmp.at (hh) ^= tmp.at (h);
67+ }
68+ }
69+
70+ return 1 ; // nonsingular
71+ }
72+
4673template <int W1, int W2>
4774std::vector<std::bitset<W2>>
48- 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) {
4976 int H = A.size (), K = B.size ();
5077 std::vector<std::bitset<W2>> C (H);
5178 for (int i = 0 ; i < H; i++) {
5279 for (int j = 0 ; j < K; j++) {
53- if (A[i][j]) C[i] ^= B[j] ;
80+ if (A. at (i). test (j)) C. at (i) ^= B. at (j) ;
5481 }
5582 }
5683 return C;
5784}
5885
5986template <int Wmax>
60- 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) {
6188 int D = X.size ();
6289 std::vector<std::bitset<Wmax>> ret (D);
6390 for (int i = 0 ; i < D; i++) ret[i][i] = 1 ;
6491 while (n) {
65- if (n & 1 ) ret = matmul <Wmax, Wmax>(ret, X);
66- 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 ;
6794 }
6895 return ret;
6996}
@@ -74,7 +101,7 @@ std::vector<std::bitset<Wmax>> matpower(std::vector<std::bitset<Wmax>> X, long l
74101// Complexity: O(HW + HW rank(A) / 64 + W^2 len(freedoms))
75102template <int Wmax, class Vec >
76103std::tuple<bool , std::bitset<Wmax>, std::vector<std::bitset<Wmax>>>
77- 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) {
78105 int H = A.size ();
79106 assert (W <= Wmax);
80107 assert (A.size () == b.size ());
@@ -84,7 +111,7 @@ system_of_linear_equations(std::vector<std::bitset<Wmax>> A, Vec b, int W) {
84111 for (int j = 0 ; j < W; ++j) M[i][j] = A[i][j];
85112 M[i][W] = b[i];
86113 }
87- M = gauss_jordan <Wmax + 1 >(W + 1 , M);
114+ M = f2_gauss_jordan <Wmax + 1 >(W + 1 , M);
88115 std::vector<int > ss (W, -1 );
89116 std::vector<int > ss_nonneg_js;
90117 for (int i = 0 ; i < H; i++) {
0 commit comments