Skip to content

Commit e9b122f

Browse files
authored
compile-time-known mod for speedup (#61)
* compiler-known mod * fix clippy * use global const mod instead --------- Co-authored-by: Luke Videckis <lukevideckis@gmail.com>
1 parent d524b0f commit e9b122f

File tree

4 files changed

+46
-54
lines changed

4 files changed

+46
-54
lines changed

examples/data_structures/seg_tree_yosupo.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
use proconio::input;
44
use programming_team_code_rust::data_structures::seg_tree::SegTree;
55

6+
const MOD: u64 = 998_244_353;
7+
68
fn main() {
79
input! {
810
n: usize,
@@ -12,16 +14,16 @@ fn main() {
1214
let a = (0..n)
1315
.map(|_| {
1416
input! {
15-
c: usize,
16-
d: usize
17+
c: u64,
18+
d: u64
1719
}
1820
(c, d)
1921
})
20-
.collect::<Vec<(usize, usize)>>();
22+
.collect::<Vec<(u64, u64)>>();
2123

22-
let mut seg_tree = SegTree::<(usize, usize)>::build_on_array(
24+
let mut seg_tree = SegTree::<(u64, u64)>::build_on_array(
2325
&a,
24-
move |x, y| (x.0 * y.0 % 998244353, (y.0 * x.1 + y.1) % 998244353),
26+
move |x, y| (x.0 * y.0 % MOD, (y.0 * x.1 + y.1) % MOD),
2527
(1, 0),
2628
);
2729

@@ -34,19 +36,19 @@ fn main() {
3436
0 => {
3537
input! {
3638
idx: usize,
37-
c: usize,
38-
d: usize
39+
c: u64,
40+
d: u64
3941
}
4042
seg_tree.set(idx, (c, d));
4143
}
4244
_ => {
4345
input! {
4446
le: usize,
4547
ri: usize,
46-
x: usize
48+
x: u64
4749
}
4850
let (c, d) = seg_tree.query(le..ri);
49-
println!("{}", (c * x + d) % 998244353);
51+
println!("{}", (c * x + d) % MOD);
5052
}
5153
}
5254
}

examples/graphs/hld_path_composite_yosupo.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use proconio::input;
44
use programming_team_code_rust::data_structures::seg_tree::SegTree;
55
use programming_team_code_rust::graphs::hld::HLD;
66

7+
const MOD: u64 = 998_244_353;
8+
79
fn main() {
810
input! {
911
n: usize,
@@ -13,12 +15,12 @@ fn main() {
1315
let a = (0..n)
1416
.map(|_| {
1517
input! {
16-
c: usize,
17-
d: usize
18+
c: u64,
19+
d: u64
1820
}
1921
(c, d)
2022
})
21-
.collect::<Vec<(usize, usize)>>();
23+
.collect::<Vec<(u64, u64)>>();
2224

2325
input! {
2426
edges: [(usize, usize); n - 1],
@@ -37,14 +39,14 @@ fn main() {
3739
input_a[hld.tin[i]] = elem;
3840
}
3941

40-
let mut st_forwards = SegTree::<(usize, usize)>::build_on_array(
42+
let mut st_forwards = SegTree::<(u64, u64)>::build_on_array(
4143
&input_a,
42-
move |x, y| (x.0 * y.0 % 998244353, (y.0 * x.1 + y.1) % 998244353),
44+
move |x, y| (x.0 * y.0 % MOD, (y.0 * x.1 + y.1) % MOD),
4345
(1, 0),
4446
);
45-
let mut st_backwards = SegTree::<(usize, usize)>::build_on_array(
47+
let mut st_backwards = SegTree::<(u64, u64)>::build_on_array(
4648
&input_a,
47-
move |x, y| (x.0 * y.0 % 998244353, (x.0 * y.1 + x.1) % 998244353),
49+
move |x, y| (x.0 * y.0 % MOD, (x.0 * y.1 + x.1) % MOD),
4850
(1, 0),
4951
);
5052

@@ -57,8 +59,8 @@ fn main() {
5759
0 => {
5860
input! {
5961
u: usize,
60-
c: usize,
61-
d: usize
62+
c: u64,
63+
d: u64
6264
}
6365
st_forwards.set(hld.tin[u], (c, d));
6466
st_backwards.set(hld.tin[u], (c, d));
@@ -67,7 +69,7 @@ fn main() {
6769
input! {
6870
u: usize,
6971
v: usize,
70-
x: usize
72+
x: u64
7173
}
7274
let (mut u_anc_val, mut v_anc_val) = (st_forwards.unit, st_backwards.unit);
7375
hld.path(u, v, |range, v_anc| {
@@ -78,7 +80,7 @@ fn main() {
7880
}
7981
});
8082
let res = (st_forwards.op)(&u_anc_val, &v_anc_val);
81-
println!("{}", (res.0 * x + res.1) % 998244353);
83+
println!("{}", (res.0 * x + res.1) % MOD);
8284
}
8385
}
8486
}

examples/numbers/binom.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
1-
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod
1+
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/problems/DPL_5_E
22

33
use proconio::input;
44
use programming_team_code_rust::numbers::binom::Binom;
55

66
fn main() {
77
input! {
8-
t: usize,
9-
m: u64,
10-
}
11-
let mut binom = Binom::new(m);
12-
for _ in 0..t {
13-
input! {
14-
n: usize,
15-
k: usize,
16-
}
17-
println!("{}", binom.comb(n, k));
8+
n: usize,
9+
k: usize,
1810
}
11+
let mut binom = Binom::default();
12+
println!("{}", binom.comb(k, n));
1913
}

src/numbers/binom.rs

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,49 @@
11
//! # Binomial Coefficient
22
3+
const MOD: u64 = 1_000_000_007;
4+
35
/// # Example
46
/// ```
57
/// use programming_team_code_rust::numbers::binom::Binom;
68
///
7-
/// let mut binom = Binom::new(1_000_000_007);
9+
/// let mut binom = Binom::default();
810
/// assert_eq!(binom.comb(5, 2), 10);
911
/// assert_eq!(binom.comb(10, 3), 120);
1012
/// ```
1113
pub struct Binom {
1214
inv: Vec<u64>,
1315
fact: Vec<u64>,
1416
inv_fact: Vec<u64>,
15-
modulo: u64,
1617
}
1718

18-
impl Binom {
19-
/// Create a new instance of Binom.
20-
///
21-
/// # Complexity
22-
/// - Time: O(1)
23-
/// - Space: O(1)
24-
pub fn new(modulo: u64) -> Binom {
25-
Binom {
26-
inv: vec![1; 2],
27-
fact: vec![1; 2],
28-
inv_fact: vec![1; 2],
29-
modulo,
19+
impl Default for Binom {
20+
fn default() -> Self {
21+
Self {
22+
inv: vec![1, 1],
23+
fact: vec![1, 1],
24+
inv_fact: vec![1, 1],
3025
}
3126
}
27+
}
3228

29+
impl Binom {
3330
/// Calculate C(n, k)
3431
///
3532
/// # Complexity
3633
/// - Time: O(1) amortized O(n)
3734
/// - Space: O(n)
3835
pub fn comb(&mut self, n: usize, k: usize) -> u64 {
39-
assert!((n as u64) < self.modulo);
36+
assert!((n as u64) < MOD);
4037
if n < k {
4138
return 0;
4239
}
4340
while self.inv.len() <= n {
4441
let i = self.inv.len();
45-
self.inv.push(
46-
self.modulo
47-
- (self.modulo / i as u64) * self.inv[self.modulo as usize % i] % self.modulo,
48-
);
49-
self.fact.push(self.fact[i - 1] * i as u64 % self.modulo);
50-
self.inv_fact
51-
.push(self.inv_fact[i - 1] * self.inv[i] % self.modulo);
42+
self.inv
43+
.push(MOD - (MOD / i as u64) * self.inv[MOD as usize % i] % MOD);
44+
self.fact.push(self.fact[i - 1] * i as u64 % MOD);
45+
self.inv_fact.push(self.inv_fact[i - 1] * self.inv[i] % MOD);
5246
}
53-
self.fact[n] * self.inv_fact[k] % self.modulo * self.inv_fact[n - k] % self.modulo
47+
self.fact[n] * self.inv_fact[k] % MOD * self.inv_fact[n - k] % MOD
5448
}
5549
}

0 commit comments

Comments
 (0)