pub struct QuotientArray<T> { /* private fields */ }
Expand description
store with index ${\lfloor\frac{n}{i}\rfloor \mid i=1,2,\ldots,n}$
Implementations§
Source§impl<T> QuotientArray<T>
impl<T> QuotientArray<T>
Sourcepub fn index_iter(n: u64, isqrtn: u64) -> impl Iterator<Item = u64>
pub fn index_iter(n: u64, isqrtn: u64) -> impl Iterator<Item = u64>
Examples found in repository?
crates/competitive/src/math/quotient_array.rs (line 54)
52 pub fn from_fn(n: u64, f: impl FnMut(u64) -> T) -> Self {
53 let isqrtn = (n as f64).sqrt().floor() as u64;
54 let data = Self::index_iter(n, isqrtn).map(f).collect();
55 Self { n, isqrtn, data }
56 }
57
58 /// convert $\sum_{i\leq n} f(i)$ to $\sum_{i\leq n, i\text{ is prime}} f(i)$
59 ///
60 /// constraints: $\mathrm{mul_p}(f(x))=f(px)$
61 pub fn lucy_dp<G>(mut self, mut mul_p: impl FnMut(T, u64) -> T) -> Self
62 where
63 G: Group<T = T>,
64 {
65 with_prime_list(self.isqrtn, |pl| {
66 for &p in pl.primes_lte(self.isqrtn) {
67 let k = self.quotient_index(p - 1);
68 let p2 = p * p;
69 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
70 if q < p2 {
71 break;
72 }
73 let diff = mul_p(G::rinv_operate(&self[q / p], &self.data[k]), p);
74 G::rinv_operate_assign(&mut self.data[i], &diff);
75 }
76 }
77 });
78 self
79 }
80
81 /// convert $\sum_{i\leq n, i\text{ is prime}} f(i)$ to $\sum_{i\leq n} f(i)$
82 pub fn min_25_sieve<R>(&self, mut f: impl FnMut(u64, u32) -> T) -> Self
83 where
84 T: Clone + One,
85 R: Ring<T = T>,
86 R::Additive: Invertible,
87 {
88 let mut dp = self.clone();
89 with_prime_list(self.isqrtn, |pl| {
90 for &p in pl.primes_lte(self.isqrtn).iter().rev() {
91 let k = self.quotient_index(p);
92 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
93 let mut pc = p;
94 if pc * p > q {
95 break;
96 }
97 let mut c = 1;
98 while q / p >= pc {
99 let x = R::mul(&f(p, c), &(R::sub(&dp[q / pc], &self.data[k])));
100 let x = R::add(&x, &f(p, c + 1));
101 dp.data[i] = R::add(&dp.data[i], &x);
102 c += 1;
103 pc *= p;
104 }
105 }
106 }
107 });
108 for x in &mut dp.data {
109 *x = R::add(x, &T::one());
110 }
111 dp
112 }
Sourcepub fn map<U>(&self, f: impl FnMut(&T) -> U) -> QuotientArray<U>
pub fn map<U>(&self, f: impl FnMut(&T) -> U) -> QuotientArray<U>
Examples found in repository?
crates/library_checker/src/math/sum_of_totient_function.rs (line 21)
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}
Sourcepub fn quotient_index(&self, i: u64) -> usize
pub fn quotient_index(&self, i: u64) -> usize
Examples found in repository?
crates/competitive/src/math/quotient_array.rs (line 67)
61 pub fn lucy_dp<G>(mut self, mut mul_p: impl FnMut(T, u64) -> T) -> Self
62 where
63 G: Group<T = T>,
64 {
65 with_prime_list(self.isqrtn, |pl| {
66 for &p in pl.primes_lte(self.isqrtn) {
67 let k = self.quotient_index(p - 1);
68 let p2 = p * p;
69 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
70 if q < p2 {
71 break;
72 }
73 let diff = mul_p(G::rinv_operate(&self[q / p], &self.data[k]), p);
74 G::rinv_operate_assign(&mut self.data[i], &diff);
75 }
76 }
77 });
78 self
79 }
80
81 /// convert $\sum_{i\leq n, i\text{ is prime}} f(i)$ to $\sum_{i\leq n} f(i)$
82 pub fn min_25_sieve<R>(&self, mut f: impl FnMut(u64, u32) -> T) -> Self
83 where
84 T: Clone + One,
85 R: Ring<T = T>,
86 R::Additive: Invertible,
87 {
88 let mut dp = self.clone();
89 with_prime_list(self.isqrtn, |pl| {
90 for &p in pl.primes_lte(self.isqrtn).iter().rev() {
91 let k = self.quotient_index(p);
92 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
93 let mut pc = p;
94 if pc * p > q {
95 break;
96 }
97 let mut c = 1;
98 while q / p >= pc {
99 let x = R::mul(&f(p, c), &(R::sub(&dp[q / pc], &self.data[k])));
100 let x = R::add(&x, &f(p, c + 1));
101 dp.data[i] = R::add(&dp.data[i], &x);
102 c += 1;
103 pc *= p;
104 }
105 }
106 }
107 });
108 for x in &mut dp.data {
109 *x = R::add(x, &T::one());
110 }
111 dp
112 }
113}
114
115impl<T> Index<u64> for QuotientArray<T> {
116 type Output = T;
117 fn index(&self, i: u64) -> &Self::Output {
118 unsafe { self.data.get_unchecked(self.quotient_index(i)) }
119 }
120}
121
122impl<T> IndexMut<u64> for QuotientArray<T> {
123 fn index_mut(&mut self, index: u64) -> &mut Self::Output {
124 let i = self.quotient_index(index);
125 unsafe { self.data.get_unchecked_mut(i) }
126 }
Sourcepub fn from_fn(n: u64, f: impl FnMut(u64) -> T) -> Self
pub fn from_fn(n: u64, f: impl FnMut(u64) -> T) -> Self
Examples found in repository?
More examples
crates/library_checker/src/math/sum_of_totient_function.rs (line 20)
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}
Sourcepub fn lucy_dp<G>(self, mul_p: impl FnMut(T, u64) -> T) -> Selfwhere
G: Group<T = T>,
pub fn lucy_dp<G>(self, mul_p: impl FnMut(T, u64) -> T) -> Selfwhere
G: Group<T = T>,
convert $\sum_{i\leq n} f(i)$ to $\sum_{i\leq n, i\text{ is prime}} f(i)$
constraints: $\mathrm{mul_p}(f(x))=f(px)$
Examples found in repository?
More examples
crates/library_checker/src/math/sum_of_totient_function.rs (line 22)
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}
Sourcepub fn min_25_sieve<R>(&self, f: impl FnMut(u64, u32) -> T) -> Self
pub fn min_25_sieve<R>(&self, f: impl FnMut(u64, u32) -> T) -> Self
convert $\sum_{i\leq n, i\text{ is prime}} f(i)$ to $\sum_{i\leq n} f(i)$
Examples found in repository?
crates/library_checker/src/math/sum_of_totient_function.rs (lines 24-35)
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}
Trait Implementations§
Source§impl<T: Clone> Clone for QuotientArray<T>
impl<T: Clone> Clone for QuotientArray<T>
Source§fn clone(&self) -> QuotientArray<T>
fn clone(&self) -> QuotientArray<T>
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moreSource§impl<T: Debug> Debug for QuotientArray<T>
impl<T: Debug> Debug for QuotientArray<T>
Source§impl<T> Index<u64> for QuotientArray<T>
impl<T> Index<u64> for QuotientArray<T>
Auto Trait Implementations§
impl<T> Freeze for QuotientArray<T>
impl<T> RefUnwindSafe for QuotientArray<T>where
T: RefUnwindSafe,
impl<T> Send for QuotientArray<T>where
T: Send,
impl<T> Sync for QuotientArray<T>where
T: Sync,
impl<T> Unpin for QuotientArray<T>where
T: Unpin,
impl<T> UnwindSafe for QuotientArray<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more