Skip to main content

U32Map

Struct U32Map 

Source
struct U32Map {
    keys: Box<[u32]>,
    values: Box<[u32]>,
    mask: usize,
}

Fields§

§keys: Box<[u32]>§values: Box<[u32]>§mask: usize

Implementations§

Source§

impl U32Map

Source

fn new(capacity: usize) -> Self

Examples found in repository?
crates/competitive/src/math/fast_prime_mod.rs (line 248)
227fn build_log<const P: u32>(root: u32, pow_lo: &[u32], pow_hi: &[u32]) -> Box<[u32]> {
228    let k = table_k::<P>();
229    let ord = P - 1;
230    let mut lpf = vec![0; k + 1].into_boxed_slice();
231    let mut primes = vec![];
232    lpf[1] = 1;
233    for i in 2..=k {
234        if lpf[i] == 0 {
235            lpf[i] = i as u32;
236            primes.push(i as u32);
237        }
238        for &p in primes.iter() {
239            let p = p as usize;
240            if p > lpf[i] as usize || p > k / i {
241                break;
242            }
243            lpf[i * p] = p as u32;
244        }
245    }
246
247    let baby_size = (BSGS_SIZE as u32).min(ord);
248    let mut baby = U32Map::new(baby_size as usize);
249    let mut pw = 1;
250    for i in 0..baby_size {
251        baby.insert(pw, i);
252        pw = mul_mod_raw::<P>(pw, root);
253    }
254    let q = pow_root_raw::<P>(ord - baby_size, pow_lo, pow_hi);
255
256    let mut log = vec![0; table_len::<P>()].into_boxed_slice();
257    log[k + 1] = 0;
258    let mut rng = Xorshift::default();
259    let small_primes = [2, 3, 5, 7, 11, 13, 17, 19];
260    for i in 2..=k {
261        let p = lpf[i] as usize;
262        if p < i {
263            log[k + i] = add_mod(log[k + p], log[k + i / p], ord);
264        } else if i < 100 {
265            let mut x = i as u32;
266            let mut ans = 0;
267            loop {
268                if let Some(v) = baby.get(x) {
269                    log[k + i] = ans + v;
270                    break;
271                }
272                ans += baby_size;
273                x = mul_mod_raw::<P>(x, q);
274            }
275        } else if i > P as usize / i {
276            let j = (P as usize) / i;
277            let r = (P as usize) % i;
278            let x = add_mod(log[k + r], ord / 2, ord);
279            let y = log[k + j];
280            log[k + i] = if x >= y { x - y } else { x + ord - y };
281        } else {
282            loop {
283                let exp = rng.rand(ord as u64) as u32;
284                let mut ans = if exp == 0 { 0 } else { ord - exp };
285                let mut x = mul_mod_raw::<P>(i as u32, pow_root_raw::<P>(exp, pow_lo, pow_hi));
286                for q in small_primes {
287                    while x.is_multiple_of(q) {
288                        x /= q;
289                        ans = add_mod(ans, log[k + q as usize], ord);
290                    }
291                }
292                if x as usize >= k {
293                    continue;
294                }
295                while (i as u32) < x && lpf[x as usize] < i as u32 {
296                    let q = lpf[x as usize];
297                    x /= q;
298                    ans = add_mod(ans, log[k + q as usize], ord);
299                }
300                if 1 < x && x < i as u32 {
301                    ans = add_mod(ans, log[k + x as usize], ord);
302                    x = 1;
303                }
304                if x == 1 {
305                    log[k + i] = ans;
306                    break;
307                }
308            }
309        }
310    }
311    for i in 1..=k {
312        log[k - i] = add_mod(log[k + i], ord / 2, ord);
313    }
314    log
315}
Source

fn insert(&mut self, key: u32, value: u32)

Examples found in repository?
crates/competitive/src/math/fast_prime_mod.rs (line 251)
227fn build_log<const P: u32>(root: u32, pow_lo: &[u32], pow_hi: &[u32]) -> Box<[u32]> {
228    let k = table_k::<P>();
229    let ord = P - 1;
230    let mut lpf = vec![0; k + 1].into_boxed_slice();
231    let mut primes = vec![];
232    lpf[1] = 1;
233    for i in 2..=k {
234        if lpf[i] == 0 {
235            lpf[i] = i as u32;
236            primes.push(i as u32);
237        }
238        for &p in primes.iter() {
239            let p = p as usize;
240            if p > lpf[i] as usize || p > k / i {
241                break;
242            }
243            lpf[i * p] = p as u32;
244        }
245    }
246
247    let baby_size = (BSGS_SIZE as u32).min(ord);
248    let mut baby = U32Map::new(baby_size as usize);
249    let mut pw = 1;
250    for i in 0..baby_size {
251        baby.insert(pw, i);
252        pw = mul_mod_raw::<P>(pw, root);
253    }
254    let q = pow_root_raw::<P>(ord - baby_size, pow_lo, pow_hi);
255
256    let mut log = vec![0; table_len::<P>()].into_boxed_slice();
257    log[k + 1] = 0;
258    let mut rng = Xorshift::default();
259    let small_primes = [2, 3, 5, 7, 11, 13, 17, 19];
260    for i in 2..=k {
261        let p = lpf[i] as usize;
262        if p < i {
263            log[k + i] = add_mod(log[k + p], log[k + i / p], ord);
264        } else if i < 100 {
265            let mut x = i as u32;
266            let mut ans = 0;
267            loop {
268                if let Some(v) = baby.get(x) {
269                    log[k + i] = ans + v;
270                    break;
271                }
272                ans += baby_size;
273                x = mul_mod_raw::<P>(x, q);
274            }
275        } else if i > P as usize / i {
276            let j = (P as usize) / i;
277            let r = (P as usize) % i;
278            let x = add_mod(log[k + r], ord / 2, ord);
279            let y = log[k + j];
280            log[k + i] = if x >= y { x - y } else { x + ord - y };
281        } else {
282            loop {
283                let exp = rng.rand(ord as u64) as u32;
284                let mut ans = if exp == 0 { 0 } else { ord - exp };
285                let mut x = mul_mod_raw::<P>(i as u32, pow_root_raw::<P>(exp, pow_lo, pow_hi));
286                for q in small_primes {
287                    while x.is_multiple_of(q) {
288                        x /= q;
289                        ans = add_mod(ans, log[k + q as usize], ord);
290                    }
291                }
292                if x as usize >= k {
293                    continue;
294                }
295                while (i as u32) < x && lpf[x as usize] < i as u32 {
296                    let q = lpf[x as usize];
297                    x /= q;
298                    ans = add_mod(ans, log[k + q as usize], ord);
299                }
300                if 1 < x && x < i as u32 {
301                    ans = add_mod(ans, log[k + x as usize], ord);
302                    x = 1;
303                }
304                if x == 1 {
305                    log[k + i] = ans;
306                    break;
307                }
308            }
309        }
310    }
311    for i in 1..=k {
312        log[k - i] = add_mod(log[k + i], ord / 2, ord);
313    }
314    log
315}
Source

fn get(&self, key: u32) -> Option<u32>

Examples found in repository?
crates/competitive/src/math/fast_prime_mod.rs (line 268)
227fn build_log<const P: u32>(root: u32, pow_lo: &[u32], pow_hi: &[u32]) -> Box<[u32]> {
228    let k = table_k::<P>();
229    let ord = P - 1;
230    let mut lpf = vec![0; k + 1].into_boxed_slice();
231    let mut primes = vec![];
232    lpf[1] = 1;
233    for i in 2..=k {
234        if lpf[i] == 0 {
235            lpf[i] = i as u32;
236            primes.push(i as u32);
237        }
238        for &p in primes.iter() {
239            let p = p as usize;
240            if p > lpf[i] as usize || p > k / i {
241                break;
242            }
243            lpf[i * p] = p as u32;
244        }
245    }
246
247    let baby_size = (BSGS_SIZE as u32).min(ord);
248    let mut baby = U32Map::new(baby_size as usize);
249    let mut pw = 1;
250    for i in 0..baby_size {
251        baby.insert(pw, i);
252        pw = mul_mod_raw::<P>(pw, root);
253    }
254    let q = pow_root_raw::<P>(ord - baby_size, pow_lo, pow_hi);
255
256    let mut log = vec![0; table_len::<P>()].into_boxed_slice();
257    log[k + 1] = 0;
258    let mut rng = Xorshift::default();
259    let small_primes = [2, 3, 5, 7, 11, 13, 17, 19];
260    for i in 2..=k {
261        let p = lpf[i] as usize;
262        if p < i {
263            log[k + i] = add_mod(log[k + p], log[k + i / p], ord);
264        } else if i < 100 {
265            let mut x = i as u32;
266            let mut ans = 0;
267            loop {
268                if let Some(v) = baby.get(x) {
269                    log[k + i] = ans + v;
270                    break;
271                }
272                ans += baby_size;
273                x = mul_mod_raw::<P>(x, q);
274            }
275        } else if i > P as usize / i {
276            let j = (P as usize) / i;
277            let r = (P as usize) % i;
278            let x = add_mod(log[k + r], ord / 2, ord);
279            let y = log[k + j];
280            log[k + i] = if x >= y { x - y } else { x + ord - y };
281        } else {
282            loop {
283                let exp = rng.rand(ord as u64) as u32;
284                let mut ans = if exp == 0 { 0 } else { ord - exp };
285                let mut x = mul_mod_raw::<P>(i as u32, pow_root_raw::<P>(exp, pow_lo, pow_hi));
286                for q in small_primes {
287                    while x.is_multiple_of(q) {
288                        x /= q;
289                        ans = add_mod(ans, log[k + q as usize], ord);
290                    }
291                }
292                if x as usize >= k {
293                    continue;
294                }
295                while (i as u32) < x && lpf[x as usize] < i as u32 {
296                    let q = lpf[x as usize];
297                    x /= q;
298                    ans = add_mod(ans, log[k + q as usize], ord);
299                }
300                if 1 < x && x < i as u32 {
301                    ans = add_mod(ans, log[k + x as usize], ord);
302                    x = 1;
303                }
304                if x == 1 {
305                    log[k + i] = ans;
306                    break;
307                }
308            }
309        }
310    }
311    for i in 1..=k {
312        log[k - i] = add_mod(log[k + i], ord / 2, ord);
313    }
314    log
315}
Source

fn index(&self, key: u32) -> usize

Examples found in repository?
crates/competitive/src/math/fast_prime_mod.rs (line 383)
381    fn insert(&mut self, key: u32, value: u32) {
382        debug_assert_ne!(key, 0);
383        let mut i = self.index(key);
384        while self.keys[i] != 0 && self.keys[i] != key {
385            i = (i + 1) & self.mask;
386        }
387        self.keys[i] = key;
388        self.values[i] = value;
389    }
390
391    fn get(&self, key: u32) -> Option<u32> {
392        debug_assert_ne!(key, 0);
393        let mut i = self.index(key);
394        while self.keys[i] != 0 {
395            if self.keys[i] == key {
396                return Some(self.values[i]);
397            }
398            i = (i + 1) & self.mask;
399        }
400        None
401    }

Auto Trait Implementations§

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> 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> ToArrayVecScalar for T

Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.