pub struct QuotientArray<T> {
n: u64,
isqrtn: u64,
data: Vec<T>,
}Expand description
store with index ${\lfloor\frac{n}{i}\rfloor \mid i=1,2,\ldots,n}$
Fields§
§n: u64§isqrtn: u64§data: Vec<T>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 let max_n = self.isqrtn as u32;
66 with_prime_list(max_n, |pl| {
67 for p in pl.primes_lte(max_n) {
68 let p = u64::from(p);
69 let k = self.quotient_index(p - 1);
70 let p2 = p * p;
71 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
72 if q < p2 {
73 break;
74 }
75 let diff = mul_p(G::rinv_operate(&self[q / p], &self.data[k]), p);
76 G::rinv_operate_assign(&mut self.data[i], &diff);
77 }
78 }
79 });
80 self
81 }
82
83 /// convert $\sum_{i\leq n, i\text{ is prime}} f(i)$ to $\sum_{i\leq n} f(i)$
84 pub fn min_25_sieve<R>(&self, mut f: impl FnMut(u64, u32) -> T) -> Self
85 where
86 T: Clone + One,
87 R: Ring<T = T, Additive: Invertible>,
88 {
89 let mut dp = self.clone();
90 let max_n = self.isqrtn as u32;
91 with_prime_list(max_n, |pl| {
92 for p in pl.primes_lte(max_n).rev() {
93 let p = u64::from(p);
94 let k = self.quotient_index(p);
95 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
96 let mut pc = p;
97 if pc * p > q {
98 break;
99 }
100 let mut c = 1;
101 while q / p >= pc {
102 let x = R::mul(&f(p, c), &(R::sub(&dp[q / pc], &self.data[k])));
103 let x = R::add(&x, &f(p, c + 1));
104 dp.data[i] = R::add(&dp.data[i], &x);
105 c += 1;
106 pc *= p;
107 }
108 }
109 }
110 });
111 for x in &mut dp.data {
112 *x = R::add(x, &T::one());
113 }
114 dp
115 }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/number_theory/sum_of_totient_function.rs (line 17)
9pub fn sum_of_totient_function(reader: impl Read, writer: impl Write) {
10 prepare_io!(reader, writer);
11 sc!(n: u64);
12 let mut s = 1;
13 let mut pp = 0;
14 let mut pc = 0;
15 let inv2 = M::new(2).inv();
16 let qa = QuotientArray::from_fn(n, |i| [M::from(i), M::from(i) * M::from(i + 1) * inv2])
17 .map(|[x, y]| [x - M::one(), y - M::one()])
18 .lucy_dp::<ArrayOperation<AdditiveOperation<_>, 2>>(|[x, y], p| [x, y * M::from(p)])
19 .map(|[x, y]| y - x)
20 .min_25_sieve::<AddMulOperation<_>>(|p, c| {
21 if pp != p || pc > c {
22 pp = p;
23 pc = 1;
24 s = p - 1;
25 }
26 while pc < c {
27 pc += 1;
28 s *= p;
29 }
30 M::from(s)
31 });
32 pp!(qa[n]);
33}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 69)
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 let max_n = self.isqrtn as u32;
66 with_prime_list(max_n, |pl| {
67 for p in pl.primes_lte(max_n) {
68 let p = u64::from(p);
69 let k = self.quotient_index(p - 1);
70 let p2 = p * p;
71 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
72 if q < p2 {
73 break;
74 }
75 let diff = mul_p(G::rinv_operate(&self[q / p], &self.data[k]), p);
76 G::rinv_operate_assign(&mut self.data[i], &diff);
77 }
78 }
79 });
80 self
81 }
82
83 /// convert $\sum_{i\leq n, i\text{ is prime}} f(i)$ to $\sum_{i\leq n} f(i)$
84 pub fn min_25_sieve<R>(&self, mut f: impl FnMut(u64, u32) -> T) -> Self
85 where
86 T: Clone + One,
87 R: Ring<T = T, Additive: Invertible>,
88 {
89 let mut dp = self.clone();
90 let max_n = self.isqrtn as u32;
91 with_prime_list(max_n, |pl| {
92 for p in pl.primes_lte(max_n).rev() {
93 let p = u64::from(p);
94 let k = self.quotient_index(p);
95 for (i, q) in Self::index_iter(self.n, self.isqrtn).enumerate() {
96 let mut pc = p;
97 if pc * p > q {
98 break;
99 }
100 let mut c = 1;
101 while q / p >= pc {
102 let x = R::mul(&f(p, c), &(R::sub(&dp[q / pc], &self.data[k])));
103 let x = R::add(&x, &f(p, c + 1));
104 dp.data[i] = R::add(&dp.data[i], &x);
105 c += 1;
106 pc *= p;
107 }
108 }
109 }
110 });
111 for x in &mut dp.data {
112 *x = R::add(x, &T::one());
113 }
114 dp
115 }
116}
117
118impl<T> Index<u64> for QuotientArray<T> {
119 type Output = T;
120 fn index(&self, i: u64) -> &Self::Output {
121 unsafe { self.data.get_unchecked(self.quotient_index(i)) }
122 }
123}
124
125impl<T> IndexMut<u64> for QuotientArray<T> {
126 fn index_mut(&mut self, index: u64) -> &mut Self::Output {
127 let i = self.quotient_index(index);
128 unsafe { self.data.get_unchecked_mut(i) }
129 }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/number_theory/sum_of_totient_function.rs (line 16)
9pub fn sum_of_totient_function(reader: impl Read, writer: impl Write) {
10 prepare_io!(reader, writer);
11 sc!(n: u64);
12 let mut s = 1;
13 let mut pp = 0;
14 let mut pc = 0;
15 let inv2 = M::new(2).inv();
16 let qa = QuotientArray::from_fn(n, |i| [M::from(i), M::from(i) * M::from(i + 1) * inv2])
17 .map(|[x, y]| [x - M::one(), y - M::one()])
18 .lucy_dp::<ArrayOperation<AdditiveOperation<_>, 2>>(|[x, y], p| [x, y * M::from(p)])
19 .map(|[x, y]| y - x)
20 .min_25_sieve::<AddMulOperation<_>>(|p, c| {
21 if pp != p || pc > c {
22 pp = p;
23 pc = 1;
24 s = p - 1;
25 }
26 while pc < c {
27 pc += 1;
28 s *= p;
29 }
30 M::from(s)
31 });
32 pp!(qa[n]);
33}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/number_theory/sum_of_totient_function.rs (line 18)
9pub fn sum_of_totient_function(reader: impl Read, writer: impl Write) {
10 prepare_io!(reader, writer);
11 sc!(n: u64);
12 let mut s = 1;
13 let mut pp = 0;
14 let mut pc = 0;
15 let inv2 = M::new(2).inv();
16 let qa = QuotientArray::from_fn(n, |i| [M::from(i), M::from(i) * M::from(i + 1) * inv2])
17 .map(|[x, y]| [x - M::one(), y - M::one()])
18 .lucy_dp::<ArrayOperation<AdditiveOperation<_>, 2>>(|[x, y], p| [x, y * M::from(p)])
19 .map(|[x, y]| y - x)
20 .min_25_sieve::<AddMulOperation<_>>(|p, c| {
21 if pp != p || pc > c {
22 pp = p;
23 pc = 1;
24 s = p - 1;
25 }
26 while pc < c {
27 pc += 1;
28 s *= p;
29 }
30 M::from(s)
31 });
32 pp!(qa[n]);
33}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/number_theory/sum_of_totient_function.rs (lines 20-31)
9pub fn sum_of_totient_function(reader: impl Read, writer: impl Write) {
10 prepare_io!(reader, writer);
11 sc!(n: u64);
12 let mut s = 1;
13 let mut pp = 0;
14 let mut pc = 0;
15 let inv2 = M::new(2).inv();
16 let qa = QuotientArray::from_fn(n, |i| [M::from(i), M::from(i) * M::from(i + 1) * inv2])
17 .map(|[x, y]| [x - M::one(), y - M::one()])
18 .lucy_dp::<ArrayOperation<AdditiveOperation<_>, 2>>(|[x, y], p| [x, y * M::from(p)])
19 .map(|[x, y]| y - x)
20 .min_25_sieve::<AddMulOperation<_>>(|p, c| {
21 if pp != p || pc > c {
22 pp = p;
23 pc = 1;
24 s = p - 1;
25 }
26 while pc < c {
27 pc += 1;
28 s *= p;
29 }
30 M::from(s)
31 });
32 pp!(qa[n]);
33}Trait Implementations§
Source§impl<T: Clone> Clone for QuotientArray<T>
impl<T: Clone> Clone for QuotientArray<T>
Source§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
Vec<T>: RefUnwindSafe,
impl<T> Send for QuotientArray<T>
impl<T> Sync for QuotientArray<T>
impl<T> Unpin for QuotientArray<T>
impl<T> UnsafeUnpin for QuotientArray<T>where
Vec<T>: UnsafeUnpin,
impl<T> UnwindSafe for QuotientArray<T>where
Vec<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