Skip to content

Commit 4517fef

Browse files
lrvideckisweb-flow
andauthored
Remove mod int (#163)
* add single function for mod division * [auto-verifier] verify commit 32fc223 * fixed some tests * more fixes * another fix * final fix * add KACTL macro * add more KACTL macros --------- Co-authored-by: GitHub <[email protected]>
1 parent 1c6156f commit 4517fef

21 files changed

+140
-350
lines changed

.verify-helper/timestamps.remote.json

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
"tests/library_checker_aizu_tests/data_structures/persistent_seg_tree.test.cpp": "2024-12-05 10:41:42 -0600",
4141
"tests/library_checker_aizu_tests/data_structures/pq_ds_undo_sliding_window.test.cpp": "2025-02-10 14:50:36 -0700",
4242
"tests/library_checker_aizu_tests/data_structures/pq_ds_undo_with_dsu.test.cpp": "2025-02-10 14:50:36 -0700",
43-
"tests/library_checker_aizu_tests/data_structures/range_parallel_dsu.test.cpp": "2025-08-28 13:19:16 -0600",
4443
"tests/library_checker_aizu_tests/data_structures/rmq_disjoint_sparse_table.test.cpp": "2024-12-15 14:34:10 -0600",
4544
"tests/library_checker_aizu_tests/data_structures/rmq_linear.test.cpp": "2025-08-14 12:01:15 -0600",
4645
"tests/library_checker_aizu_tests/data_structures/rmq_sparse_table.test.cpp": "2025-08-14 12:01:15 -0600",
@@ -65,20 +64,18 @@
6564
"tests/library_checker_aizu_tests/graphs/hopcroft_karp_aizu.test.cpp": "2025-08-14 10:27:46 -0600",
6665
"tests/library_checker_aizu_tests/graphs/hopcroft_karp_lib_checker.test.cpp": "2025-08-14 10:27:46 -0600",
6766
"tests/library_checker_aizu_tests/graphs/mst.test.cpp": "2025-08-22 13:27:42 -0600",
68-
"tests/library_checker_aizu_tests/graphs/offline_incremental_scc.test.cpp": "2025-08-28 13:19:16 -0600",
6967
"tests/library_checker_aizu_tests/graphs/strongly_connected_components_aizu.test.cpp": "2025-08-14 10:27:46 -0600",
7068
"tests/library_checker_aizu_tests/graphs/strongly_connected_components_lib_checker.test.cpp": "2025-08-14 10:27:46 -0600",
7169
"tests/library_checker_aizu_tests/graphs/two_edge_components.test.cpp": "2025-08-14 10:27:46 -0600",
7270
"tests/library_checker_aizu_tests/handmade_tests/count_paths.test.cpp": "2025-08-28 13:57:36 -0600",
7371
"tests/library_checker_aizu_tests/handmade_tests/dsu.test.cpp": "2025-08-22 13:14:15 -0600",
7472
"tests/library_checker_aizu_tests/handmade_tests/dsu_size.test.cpp": "2024-12-14 19:50:29 -0600",
75-
"tests/library_checker_aizu_tests/handmade_tests/edge_cd_small_trees.test.cpp": "2025-08-28 13:19:16 -0600",
7673
"tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp": "2025-08-28 13:19:16 -0600",
7774
"tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2025-08-06 16:18:37 -0600",
7875
"tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-14 19:50:29 -0600",
7976
"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2025-08-04 17:01:28 -0600",
8077
"tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2025-02-10 14:50:36 -0700",
81-
"tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp": "2025-08-28 13:19:16 -0600",
78+
"tests/library_checker_aizu_tests/handmade_tests/mod_division.test.cpp": "2025-09-07 15:15:17 -0600",
8279
"tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp": "2025-08-28 13:19:16 -0600",
8380
"tests/library_checker_aizu_tests/handmade_tests/permutation_tree_small.test.cpp": "2025-08-14 12:01:15 -0600",
8481
"tests/library_checker_aizu_tests/handmade_tests/rmq_small_n.test.cpp": "2025-08-14 12:01:15 -0600",
@@ -89,21 +86,14 @@
8986
"tests/library_checker_aizu_tests/loops/quotients.test.cpp": "2024-11-17 14:04:03 -0600",
9087
"tests/library_checker_aizu_tests/loops/submasks.test.cpp": "2025-02-10 14:50:36 -0700",
9188
"tests/library_checker_aizu_tests/loops/supermasks.test.cpp": "2025-02-10 14:50:36 -0700",
92-
"tests/library_checker_aizu_tests/math/binary_exponentiation_mod.test.cpp": "2025-08-28 13:19:16 -0600",
9389
"tests/library_checker_aizu_tests/math/binary_matrix_mult.test.cpp": "2024-11-17 14:04:03 -0600",
9490
"tests/library_checker_aizu_tests/math/count_paths.test.cpp": "2025-08-28 13:19:16 -0600",
9591
"tests/library_checker_aizu_tests/math/derangement.test.cpp": "2024-11-17 14:04:03 -0600",
96-
"tests/library_checker_aizu_tests/math/matrix_determinant.test.cpp": "2025-08-28 13:19:16 -0600",
9792
"tests/library_checker_aizu_tests/math/matrix_mult.test.cpp": "2024-11-17 14:04:03 -0600",
98-
"tests/library_checker_aizu_tests/math/mod_int_derangement.test.cpp": "2025-08-28 13:19:16 -0600",
99-
"tests/library_checker_aizu_tests/math/mod_int_gcd_convolution.test.cpp": "2025-08-28 13:19:16 -0600",
100-
"tests/library_checker_aizu_tests/math/mod_int_n_choose_k.test.cpp": "2025-08-28 13:19:16 -0600",
101-
"tests/library_checker_aizu_tests/math/mod_int_tetration.test.cpp": "2025-08-28 13:19:16 -0600",
10293
"tests/library_checker_aizu_tests/math/n_choose_k.test.cpp": "2025-08-28 13:19:16 -0600",
10394
"tests/library_checker_aizu_tests/math/num_subsequences.test.cpp": "2024-11-17 14:04:03 -0600",
10495
"tests/library_checker_aizu_tests/math/partitions.test.cpp": "2025-08-28 13:19:16 -0600",
10596
"tests/library_checker_aizu_tests/math/prime_sieve.test.cpp": "2024-11-22 11:54:52 -0600",
106-
"tests/library_checker_aizu_tests/math/solve_linear_mod.test.cpp": "2025-08-28 13:19:16 -0600",
10797
"tests/library_checker_aizu_tests/math/tetration.test.cpp": "2024-11-17 14:04:03 -0600",
10898
"tests/library_checker_aizu_tests/math/totient.test.cpp": "2024-11-17 14:04:03 -0600",
10999
"tests/library_checker_aizu_tests/math/xor_basis.test.cpp": "2025-08-04 20:35:27 -0600",
@@ -133,7 +123,6 @@
133123
"tests/library_checker_aizu_tests/trees/edge_cd_contour_range_query.test.cpp": "2025-08-14 10:27:46 -0600",
134124
"tests/library_checker_aizu_tests/trees/edge_cd_contour_range_update.test.cpp": "2025-08-14 10:27:46 -0600",
135125
"tests/library_checker_aizu_tests/trees/edge_cd_count_paths_per_length.test.cpp": "2025-08-14 10:27:46 -0600",
136-
"tests/library_checker_aizu_tests/trees/edge_cd_reroot_dp.test.cpp": "2025-08-28 13:19:16 -0600",
137126
"tests/library_checker_aizu_tests/trees/hld_aizu1.test.cpp": "2025-08-24 19:27:23 -0600",
138127
"tests/library_checker_aizu_tests/trees/hld_aizu2.test.cpp": "2025-08-24 19:27:23 -0600",
139128
"tests/library_checker_aizu_tests/trees/hld_lib_checker_path.test.cpp": "2025-08-24 19:27:23 -0600",
@@ -145,6 +134,5 @@
145134
"tests/library_checker_aizu_tests/trees/lca_all_methods_aizu.test.cpp": "2025-08-21 12:17:27 -0600",
146135
"tests/library_checker_aizu_tests/trees/lca_all_methods_lib_checker.test.cpp": "2025-08-21 12:17:27 -0600",
147136
"tests/library_checker_aizu_tests/trees/shallowest_aizu_tree_height.test.cpp": "2025-09-03 10:32:09 -0600",
148-
"tests/library_checker_aizu_tests/trees/shallowest_lib_checker_tree_path_composite.test.cpp": "2025-09-03 10:32:09 -0600",
149137
"tests/library_checker_aizu_tests/trees/subtree_isomorphism.test.cpp": "2025-08-14 10:27:46 -0600"
150138
}

library/math/matrix_related/row_reduce.hpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#pragma once
2-
#include "../mod_int.hpp"
2+
#include "../mod_division.hpp"
33
//! @code
44
//! auto [rank, det] = row_reduce(mat, cols);
55
//! @endcode
@@ -8,28 +8,30 @@
88
//! affected by row operations
99
//! @time O(n * m * min(cols, n))
1010
//! @space O(1)
11-
pair<int, mint> row_reduce(vector<vector<mint>>& mat,
12-
int cols) {
11+
pii row_reduce(vector<vi>& mat, int cols) {
1312
int n = sz(mat), m = sz(mat[0]), rank = 0;
14-
mint det = 1;
13+
int det = 1;
1514
for (int col = 0; col < cols && rank < n; col++) {
1615
auto it = find_if(rank + all(mat),
17-
[&](auto& v) { return v[col].x; });
16+
[&](auto& v) { return v[col]; });
1817
if (it == end(mat)) {
1918
det = 0;
2019
continue;
2120
}
2221
if (it != begin(mat) + rank) {
23-
det = mint(0) - det;
22+
det = (mod - det) % mod;
2423
iter_swap(begin(mat) + rank, it);
2524
}
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];
25+
det = 1LL * det * mat[rank][col] % mod;
26+
int a_inv = mod_div(1, mat[rank][col]);
27+
for (int& num : mat[rank])
28+
num = 1LL * num * a_inv % mod;
29+
rep(i, 0, n) if (i != rank && mat[i][col] != 0) {
30+
int num = mat[i][col];
3131
rep(j, 0, m) mat[i][j] =
32-
mat[i][j] - mat[rank][j] * num;
32+
((mat[i][j] - 1LL * mat[rank][j] * num) % mod +
33+
mod) %
34+
mod;
3335
}
3436
rank++;
3537
}

library/math/matrix_related/solve_linear_mod.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,20 @@
1111
//! @time O(n * m * min(n, m))
1212
//! @space O(m)
1313
struct solve_linear_mod {
14-
int rank;
15-
mint det;
16-
vector<mint> sol;
17-
solve_linear_mod(vector<vector<mint>>& mat,
18-
const vector<mint>& rhs) {
14+
int rank, det;
15+
vi sol;
16+
solve_linear_mod(vector<vi>& mat, const vi& rhs) {
1917
int n = sz(mat), m = sz(mat[0]);
2018
rep(i, 0, n) mat[i].push_back(rhs[i]);
2119
tie(rank, det) = row_reduce(mat, m);
2220
if (any_of(rank + all(mat),
23-
[](auto& v) { return v.back().x; })) {
21+
[](vi& v) { return v.back(); })) {
2422
return;
2523
}
2624
sol.resize(m);
2725
int j = 0;
28-
for_each(begin(mat), begin(mat) + rank, [&](auto& v) {
29-
while (v[j].x == 0) j++;
26+
for_each(begin(mat), begin(mat) + rank, [&](vi& v) {
27+
while (!v[j]) j++;
3028
sol[j] = v.back();
3129
});
3230
}

library/math/mod_division.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
const int mod = 998244353;
3+
int mod_div(int x, int y) {
4+
int m = mod, u = 1, v = 0;
5+
while (m) swap(u -= y / m * v, v), swap(y %= m, m);
6+
assert(y == 1);
7+
return 1LL * x * (u + mod) % mod;
8+
}

library/math/mod_int.hpp

Lines changed: 0 additions & 12 deletions
This file was deleted.

library/math/mod_int_division.hpp

Lines changed: 0 additions & 9 deletions
This file was deleted.

library/math/mod_int_pow.hpp

Lines changed: 0 additions & 12 deletions
This file was deleted.

tests/library_checker_aizu_tests/data_structures/range_parallel_dsu.test.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,19 @@
44
#include "../template.hpp"
55
#include "../../../library/data_structures/dsu/range_parallel_dsu.hpp"
66
#include "../../../library/data_structures/dsu/range_parallel_equivalence_classes.hpp"
7-
#include "../../../library/math/mod_int.hpp"
7+
const int mod = 998244353;
88
int main() {
99
cin.tie(0)->sync_with_stdio(0);
1010
int n, q;
1111
cin >> n >> q;
1212
rp_dsu dsu(n);
13-
vector<mint> y(n);
14-
for (int i = 0; i < n; i++) {
15-
int num;
16-
cin >> num;
17-
y[i] = num;
18-
}
19-
vector<mint> x = y;
20-
mint ans = 0;
13+
vi y(n);
14+
for (int i = 0; i < n; i++) cin >> y[i];
15+
vi x = y;
16+
int ans = 0;
2117
auto f = [&](int u, int v) {
22-
ans = ans + x[u] * x[v];
23-
x[u] = x[u] + x[v];
18+
ans = (ans + 1LL * x[u] * x[v]) % mod;
19+
x[u] = (x[u] + x[v]) % mod;
2420
};
2521
vector<array<int, 3>> queries;
2622
queries.reserve(q);
@@ -29,18 +25,19 @@ int main() {
2925
cin >> k >> a >> b;
3026
dsu.join(a, b, k, f);
3127
queries.push_back({a, b, k});
32-
cout << ans.x << '\n';
28+
cout << ans << '\n';
3329
if (qq == 0 || qq == 1 || qq == 10 || qq == 1000 ||
3430
qq == 100'000 || qq == q - 1) {
3531
auto uf = get_rp_dsu(queries, n);
36-
vector<mint> sums(n);
37-
mint offline_ans = 0;
32+
vi sums(n);
33+
int offline_ans = 0;
3834
for (int i = 0; i < n; i++) {
3935
int id = uf.find(i);
40-
offline_ans = offline_ans + sums[id] * y[i];
41-
sums[id] = sums[id] + y[i];
36+
offline_ans =
37+
(offline_ans + 1LL * sums[id] * y[i]) % mod;
38+
sums[id] = (sums[id] + y[i]) % mod;
4239
}
43-
assert(ans.x == offline_ans.x);
40+
assert(ans == offline_ans);
4441
}
4542
}
4643
return 0;

tests/library_checker_aizu_tests/graphs/offline_incremental_scc.test.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
#include "../template.hpp"
44
#include "../../../library/graphs/strongly_connected_components/offline_incremental_scc.hpp"
55
#include "../../../library/data_structures/dsu/dsu.hpp"
6-
#include "../../../library/math/mod_int.hpp"
6+
const int mod = 998244353;
77
int main() {
88
cin.tie(0)->sync_with_stdio(0);
99
int n, m;
1010
cin >> n >> m;
11-
vector<mint> xs(n);
12-
for (int i = 0; i < n; i++) cin >> xs[i].x;
11+
vector<int> xs(n);
12+
for (int i = 0; i < n; i++) cin >> xs[i];
1313
vector<array<int, 2>> eds(m);
1414
for (auto& [u, v] : eds) cin >> u >> v;
1515
auto joins = offline_incremental_scc(eds, n);
@@ -21,22 +21,22 @@ int main() {
2121
ranges::sort(all(order), {},
2222
[&](int i) { return joins[i]; });
2323
DSU dsu(n);
24-
mint sum = 0;
24+
int sum = 0;
2525
for (int t = 0, it = 0; t < m; t++) {
2626
while (it < m && joins[order[it]] <= t) {
2727
auto [u, v] = eds[order[it]];
2828
u = dsu.go(u);
2929
v = dsu.go(v);
3030
if (dsu.e[u] > dsu.e[v]) swap(u, v);
3131
if (u != v) {
32-
sum = sum + xs[u] * xs[v];
33-
xs[u] = xs[u] + xs[v];
32+
sum = (sum + 1LL * xs[u] * xs[v]) % mod;
33+
xs[u] = (xs[u] + xs[v]) % mod;
3434
xs[v] = xs[u];
3535
}
3636
dsu.join(u, v);
3737
it++;
3838
}
39-
cout << sum.x << '\n';
39+
cout << sum << '\n';
4040
}
4141
return 0;
4242
}

tests/library_checker_aizu_tests/handmade_tests/edge_cd_small_trees.test.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "../template.hpp"
44
#include "../edge_cd_asserts.hpp"
55
#include "../../../kactl/stress-tests/utilities/genTree.h"
6-
#include "../../../library/math/mod_int_pow.hpp"
76
#include "../../../library/trees/edge_cd.hpp"
87
int main() {
98
{
@@ -21,7 +20,9 @@ int main() {
2120
});
2221
}
2322
for (int n = 2; n <= 7; n++) {
24-
int num_codes = mpow(n, n - 2).x;
23+
int num_codes = 1;
24+
for (int k = 0; k < n - 2; k++) num_codes *= n;
25+
// int num_codes = mpow(n, n - 2).x;
2526
vector<vector<int>> pruf_codes(num_codes,
2627
vector<int>(n - 2));
2728
for (int i = 0; i < num_codes; i++) {

0 commit comments

Comments
 (0)