|
1 | 1 | #pragma once |
2 | | -#include "../mod_int.hpp" |
| 2 | +#include "../mod_division.hpp" |
3 | 3 | //! @code |
4 | 4 | //! auto [rank, det] = row_reduce(mat, cols); |
5 | 5 | //! @endcode |
|
8 | 8 | //! affected by row operations |
9 | 9 | //! @time O(n * m * min(cols, n)) |
10 | 10 | //! @space O(1) |
11 | | -pair<int, mint> row_reduce(vector<vector<mint>>& mat, |
| 11 | +pair<int, int> row_reduce(vector<vector<int>>& mat, |
12 | 12 | int cols) { |
13 | 13 | int n = sz(mat), m = sz(mat[0]), rank = 0; |
14 | | - mint det = 1; |
| 14 | + int det = 1; |
15 | 15 | for (int col = 0; col < cols && rank < n; col++) { |
16 | 16 | auto it = find_if(rank + all(mat), |
17 | | - [&](auto& v) { return v[col].x; }); |
| 17 | + [&](auto& v) { return v[col]; }); |
18 | 18 | if (it == end(mat)) { |
19 | 19 | det = 0; |
20 | 20 | continue; |
21 | 21 | } |
22 | 22 | if (it != begin(mat) + rank) { |
23 | | - det = mint(0) - det; |
| 23 | + det = (mod - det) % mod; |
24 | 24 | iter_swap(begin(mat) + rank, it); |
25 | 25 | } |
26 | | - det = det * mat[rank][col]; |
27 | | - mint a_inv = mint(1) / mat[rank][col]; |
28 | | - for (mint& num : mat[rank]) num = num * a_inv; |
29 | | - rep(i, 0, n) if (i != rank && mat[i][col].x != 0) { |
30 | | - mint num = mat[i][col]; |
| 26 | + det = 1LL * det * mat[rank][col] % mod; |
| 27 | + int a_inv = mod_div(1, mat[rank][col]); |
| 28 | + for (int& num : mat[rank]) |
| 29 | + num = 1LL * num * a_inv % mod; |
| 30 | + rep(i, 0, n) if (i != rank && mat[i][col] != 0) { |
| 31 | + int num = mat[i][col]; |
31 | 32 | rep(j, 0, m) mat[i][j] = |
32 | | - mat[i][j] - mat[rank][j] * num; |
| 33 | + ((mat[i][j] - 1LL * mat[rank][j] * num) % mod + |
| 34 | + mod) % |
| 35 | + mod; |
33 | 36 | } |
34 | 37 | rank++; |
35 | 38 | } |
|
0 commit comments