https://atcoder.jp/contests/math-and-algorithm/tasks/abc172_d
よくある和の順番を変えるやつですね。約数の問題では特に多いです。
とおくと、
とおくと、
となります。
これでも十分速いですが、dが大きいところではが同じものが多いので、これをまとめるとになります。
// Sum of Divisors #![allow(non_snake_case)] //////////////////// library //////////////////// fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } //////////////////// process //////////////////// fn f(N: i64) -> i64 { let r = (N as f64).sqrt() as i64; let s1 = (1..N/(r+1)+1).map(|d| d * (N/d) * (N/d + 1) / 2).sum::<i64>(); let s2 = (1..r+1).map(|r| { let first = N / (r + 1) + 1; let last = N / r + 1; (last - first) * (first + last - 1) * r * (r + 1) / 4 }). sum::<i64>(); s1 + s2 } fn main() { let N: i64 = read(); println!("{}", f(N)) }