use crate::integer_square_root_with_binary_search_u64::isqrt;
pub fn sum_of_multiples_count_range(
limit: u64,
lo: u64,
mut hi: u64,
) -> u64 {
assert!(lo > 0);
if limit < hi {
hi = limit;
}
if hi < lo {
return 0;
}
debug_assert!(lo <= hi && hi <= limit);
let mut s = 0;
let mut k: u64 = 0;
for i in lo..=hi {
if i * i > limit {
k = i;
break;
}
s += limit / i;
}
if k == 0 {
debug_assert!(hi * hi <= limit);
return s;
}
debug_assert!(k == isqrt(limit) + 1);
debug_assert!(lo <= k && k <= hi);
for j in 1..=limit / k {
let mut i_max = limit / j;
debug_assert!((i_max + 1) * j > limit);
debug_assert!(k <= i_max);
if i_max > hi {
i_max = hi;
}
s += i_max - k + 1;
}
s
}
#[cfg(test)]
mod tests {
#[test]
fn test() {
use super::*;
assert_eq!(sum_of_multiples_count_range(4, 1, 4), 8);
assert_eq!(sum_of_multiples_count_range(10, 3, 5), 7);
assert_eq!(sum_of_multiples_count_range(10, 1, 2), 15);
}
}