Struct QuotientArray

Source
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>
where T: Zero,

Source

pub fn zeros(n: u64) -> Self

Source§

impl<T> QuotientArray<T>

Source

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    }
Source

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}
Source

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    }
Source

pub fn from_fn(n: u64, f: impl FnMut(u64) -> T) -> Self

Examples found in repository?
crates/competitive/src/math/quotient_array.rs (line 17)
16    pub fn zeros(n: u64) -> Self {
17        Self::from_fn(n, |_| T::zero())
18    }
More examples
Hide additional examples
crates/library_checker/src/math/counting_primes.rs (line 10)
6pub fn counting_primes(reader: impl Read, mut writer: impl Write) {
7    let s = read_all_unchecked(reader);
8    let mut scanner = Scanner::new(&s);
9    scan!(scanner, n: u64);
10    let qa = QuotientArray::from_fn(n, |i| i as i64 - 1).lucy_dp::<AdditiveOperation<_>>(|x, _p| x);
11    writeln!(writer, "{}", qa[n]).ok();
12}
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}
Source

pub fn lucy_dp<G>(self, mul_p: impl FnMut(T, u64) -> T) -> Self
where 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?
crates/library_checker/src/math/counting_primes.rs (line 10)
6pub fn counting_primes(reader: impl Read, mut writer: impl Write) {
7    let s = read_all_unchecked(reader);
8    let mut scanner = Scanner::new(&s);
9    scan!(scanner, n: u64);
10    let qa = QuotientArray::from_fn(n, |i| i as i64 - 1).lucy_dp::<AdditiveOperation<_>>(|x, _p| x);
11    writeln!(writer, "{}", qa[n]).ok();
12}
More examples
Hide additional 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}
Source

pub fn min_25_sieve<R>(&self, f: impl FnMut(u64, u32) -> T) -> Self
where T: Clone + One, R: Ring<T = T>, R::Additive: Invertible,

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>

Source§

fn clone(&self) -> QuotientArray<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for QuotientArray<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Index<u64> for QuotientArray<T>

Source§

type Output = T

The returned type after indexing.
Source§

fn index(&self, i: u64) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<T> IndexMut<u64> for QuotientArray<T>

Source§

fn index_mut(&mut self, index: u64) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.