Skip to content

Commit 1a0a30b

Browse files
author
Takanori MAEHARA
authored
Modular Arithmetics
1 parent b0b42c6 commit 1a0a30b

1 file changed

Lines changed: 17 additions & 23 deletions

File tree

math/modular_arithmetics.cc

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ ModInt stringToModInt(string s, Int mod) {
9797
// compute inv[1], inv[2], ..., inv[mod-1] in O(n) time
9898
vector<ModInt> inverse(Int mod) {
9999
vector<ModInt> inv(mod, ModInt(0, mod));
100-
inv[1] = 1;
100+
inv[1].val = 1;
101101
for (Int a = 2; a < mod; ++a)
102-
inv[a] = inv[mod % a] * (mod - mod/a);
102+
inv[a] = inv[mod % a] * ModInt(mod - mod/a,mod);
103103
return inv;
104104
}
105105

@@ -241,32 +241,26 @@ struct ModMatrix {
241241
static ModMatrix zero(int n, Int mod) {
242242
return ModMatrix(n, n, mod);
243243
}
244-
// Gauss-Jordan-Blankinship Elimination
245-
// It can be used for any composite modulo (Euclidean domain).
244+
// mod should be prime
246245
ModMatrix inv() const {
247246
ModMatrix B = eye(n, mod);
248-
vector<vector<ModInt>> a = val;
247+
vector<vector<ModInt>> a = val;
249248
vector<vector<ModInt>> &b = B.val;
250-
for (int j = 0; j < n; ++j) {
251-
// minimum nonzero をとって
252-
// Blankinship type の吐き出しを行う
253-
for (int i = 0; i < n; ++i) {
254-
if (i == j) continue;
255-
while (a[i][j].val) {
256-
ModInt t(a[j][j].val/a[i][j].val, mod);
257-
for (int k = j; k < n; ++k) swap(a[i][k], a[j][k]-=t*a[i][k]);
258-
for (int k = 0; k < n; ++k) swap(b[i][k], b[j][k]-=t*b[i][k]);
259-
}
260-
}
261-
if (a[j][j].val == 0) return ModMatrix(0,0,0);
262-
}
263-
for (int i = 0; i < n; ++i) {
264-
for (int j = 0; j < n; ++j) {
265-
cout << a[i][j] << " ";
249+
for (int i = 0, j, k; i < n; ++i) {
250+
for (j = i; j < n && a[j][i].val == 0; ++j);
251+
if (j == n) return ModMatrix(0,0,0); // regularity is checked by m = 0
252+
swap(a[i], a[j]);
253+
swap(b[i], b[j]);
254+
ModInt inv = a[i][i].inv();
255+
for (k = i; k < n; ++k) a[i][k] *= inv;
256+
for (k = 0; k < n; ++k) b[i][k] *= inv;
257+
for (j = 0; j < n; ++j) {
258+
if (i == j || a[j][i].val == 0) continue;
259+
ModInt c = a[j][i];
260+
for (k = i; k < n; ++k) a[j][k] -= c * a[i][k];
261+
for (k = 0; k < n; ++k) b[j][k] -= c * b[i][k];
266262
}
267-
cout << endl
268263
}
269-
270264
return B;
271265
}
272266
// It can be used for any composite modulo.

0 commit comments

Comments
 (0)