library_checker/math/
sum_of_totient_function.rs1#[doc(no_inline)]
2pub use competitive::{
3 algebra::{AddMulOperation, AdditiveOperation, ArrayOperation},
4 math::QuotientArray,
5 num::mint_basic::MInt998244353,
6};
7use competitive::{num::One, prelude::*};
8
9type M = MInt998244353;
10
11#[verify::library_checker("sum_of_totient_function")]
12pub fn sum_of_totient_function(reader: impl Read, mut writer: impl Write) {
13 let s = read_all_unchecked(reader);
14 let mut scanner = Scanner::new(&s);
15 scan!(scanner, n: u64);
16 let mut s = 1;
17 let mut pp = 0;
18 let mut pc = 0;
19 let inv2 = M::new(2).inv();
20 let qa = QuotientArray::from_fn(n, |i| [M::from(i), M::from(i) * M::from(i + 1) * inv2])
21 .map(|[x, y]| [x - M::one(), y - M::one()])
22 .lucy_dp::<ArrayOperation<AdditiveOperation<_>, 2>>(|[x, y], p| [x, y * M::from(p)])
23 .map(|[x, y]| y - x)
24 .min_25_sieve::<AddMulOperation<_>>(|p, c| {
25 if pp != p || pc > c {
26 pp = p;
27 pc = 1;
28 s = p - 1;
29 }
30 while pc < c {
31 pc += 1;
32 s *= p;
33 }
34 M::from(s)
35 });
36 writeln!(writer, "{}", qa[n]).ok();
37}