Skip to main content

FloorSum

Struct FloorSum 

Source
struct FloorSum<R, const X: usize, const Y: usize>
where R: SemiRing,
{ _marker: PhantomData<fn() -> R>, }

Fields§

§_marker: PhantomData<fn() -> R>

Implementations§

Source§

impl<R, const X: usize, const Y: usize> FloorSum<R, X, Y>
where R: SemiRing,

Source

fn to_x() -> FloorSumData<R, X, Y>

Examples found in repository?
crates/competitive/src/math/floor_sum.rs (line 338)
327pub fn floor_sum_polynomial<T, const X: usize, const Y: usize>(
328    n: u64,
329    a: u64,
330    b: u64,
331    m: u64,
332) -> [[T; Y]; X]
333where
334    T: DotProduct + One,
335{
336    debug_assert!(a == 0 || n < (u64::MAX - b) / a);
337    floor_monoid_product::<FloorSum<AddMulOperation<T>, X, Y>>(
338        FloorSum::<AddMulOperation<T>, X, Y>::to_x(),
339        FloorSum::<AddMulOperation<T>, X, Y>::to_y(),
340        n,
341        a,
342        b,
343        m,
344    )
345    .dp
346}
347
348/// $$\sum_{i=l}^{r-1}i^X\left\lfloor\frac{a\times i+b}{m}\right\rfloor^Y$$
349pub fn floor_sum_polynomial_i64<T, const X: usize, const Y: usize>(
350    l: i64,
351    r: i64,
352    a: i64,
353    b: i64,
354    m: u64,
355) -> [[T; Y]; X]
356where
357    T: DotProduct + One,
358    AddMulOperation<T>: SemiRing<T = T, Additive: Invertible>,
359{
360    assert!(l <= r);
361    assert!(m > 0);
362
363    if a < 0 {
364        let mut ans = floor_sum_polynomial_i64::<T, X, Y>(-r + 1, -l + 1, -a, b, m);
365        for ans in ans.iter_mut().skip(1).step_by(2) {
366            for ans in ans.iter_mut() {
367                *ans = AddMulOperation::<T>::neg(ans);
368            }
369        }
370        return ans;
371    }
372
373    let add_x = l;
374    let n = (r - l) as u64;
375    let b = a * add_x + b;
376
377    let add_y = b.div_euclid(m as i64);
378    let b = b.rem_euclid(m as i64);
379    assert!(a >= 0);
380    assert!(b >= 0);
381    let data = floor_monoid_product::<FloorSum<AddMulOperation<T>, X, Y>>(
382        FloorSum::<AddMulOperation<T>, X, Y>::to_x(),
383        FloorSum::<AddMulOperation<T>, X, Y>::to_y(),
384        n,
385        a as u64,
386        b as u64,
387        m,
388    );
389
390    let offset = FloorSum::<AddMulOperation<T>, X, Y>::offset(add_x, add_y);
391    FloorSum::<AddMulOperation<T>, X, Y>::operate(&offset, &data).dp
392}
Source

fn to_y() -> FloorSumData<R, X, Y>

Examples found in repository?
crates/competitive/src/math/floor_sum.rs (line 339)
327pub fn floor_sum_polynomial<T, const X: usize, const Y: usize>(
328    n: u64,
329    a: u64,
330    b: u64,
331    m: u64,
332) -> [[T; Y]; X]
333where
334    T: DotProduct + One,
335{
336    debug_assert!(a == 0 || n < (u64::MAX - b) / a);
337    floor_monoid_product::<FloorSum<AddMulOperation<T>, X, Y>>(
338        FloorSum::<AddMulOperation<T>, X, Y>::to_x(),
339        FloorSum::<AddMulOperation<T>, X, Y>::to_y(),
340        n,
341        a,
342        b,
343        m,
344    )
345    .dp
346}
347
348/// $$\sum_{i=l}^{r-1}i^X\left\lfloor\frac{a\times i+b}{m}\right\rfloor^Y$$
349pub fn floor_sum_polynomial_i64<T, const X: usize, const Y: usize>(
350    l: i64,
351    r: i64,
352    a: i64,
353    b: i64,
354    m: u64,
355) -> [[T; Y]; X]
356where
357    T: DotProduct + One,
358    AddMulOperation<T>: SemiRing<T = T, Additive: Invertible>,
359{
360    assert!(l <= r);
361    assert!(m > 0);
362
363    if a < 0 {
364        let mut ans = floor_sum_polynomial_i64::<T, X, Y>(-r + 1, -l + 1, -a, b, m);
365        for ans in ans.iter_mut().skip(1).step_by(2) {
366            for ans in ans.iter_mut() {
367                *ans = AddMulOperation::<T>::neg(ans);
368            }
369        }
370        return ans;
371    }
372
373    let add_x = l;
374    let n = (r - l) as u64;
375    let b = a * add_x + b;
376
377    let add_y = b.div_euclid(m as i64);
378    let b = b.rem_euclid(m as i64);
379    assert!(a >= 0);
380    assert!(b >= 0);
381    let data = floor_monoid_product::<FloorSum<AddMulOperation<T>, X, Y>>(
382        FloorSum::<AddMulOperation<T>, X, Y>::to_x(),
383        FloorSum::<AddMulOperation<T>, X, Y>::to_y(),
384        n,
385        a as u64,
386        b as u64,
387        m,
388    );
389
390    let offset = FloorSum::<AddMulOperation<T>, X, Y>::offset(add_x, add_y);
391    FloorSum::<AddMulOperation<T>, X, Y>::operate(&offset, &data).dp
392}
Source§

impl<R, const X: usize, const Y: usize> FloorSum<R, X, Y>
where R: Ring<Additive: Invertible>,

Source

fn offset(x: i64, y: i64) -> FloorSumData<R, X, Y>

Examples found in repository?
crates/competitive/src/math/floor_sum.rs (line 390)
349pub fn floor_sum_polynomial_i64<T, const X: usize, const Y: usize>(
350    l: i64,
351    r: i64,
352    a: i64,
353    b: i64,
354    m: u64,
355) -> [[T; Y]; X]
356where
357    T: DotProduct + One,
358    AddMulOperation<T>: SemiRing<T = T, Additive: Invertible>,
359{
360    assert!(l <= r);
361    assert!(m > 0);
362
363    if a < 0 {
364        let mut ans = floor_sum_polynomial_i64::<T, X, Y>(-r + 1, -l + 1, -a, b, m);
365        for ans in ans.iter_mut().skip(1).step_by(2) {
366            for ans in ans.iter_mut() {
367                *ans = AddMulOperation::<T>::neg(ans);
368            }
369        }
370        return ans;
371    }
372
373    let add_x = l;
374    let n = (r - l) as u64;
375    let b = a * add_x + b;
376
377    let add_y = b.div_euclid(m as i64);
378    let b = b.rem_euclid(m as i64);
379    assert!(a >= 0);
380    assert!(b >= 0);
381    let data = floor_monoid_product::<FloorSum<AddMulOperation<T>, X, Y>>(
382        FloorSum::<AddMulOperation<T>, X, Y>::to_x(),
383        FloorSum::<AddMulOperation<T>, X, Y>::to_y(),
384        n,
385        a as u64,
386        b as u64,
387        m,
388    );
389
390    let offset = FloorSum::<AddMulOperation<T>, X, Y>::offset(add_x, add_y);
391    FloorSum::<AddMulOperation<T>, X, Y>::operate(&offset, &data).dp
392}

Trait Implementations§

Source§

impl<R, const X: usize, const Y: usize> Associative for FloorSum<R, X, Y>
where R: SemiRing,

Source§

impl<R, const X: usize, const Y: usize> Magma for FloorSum<R, X, Y>
where R: SemiRing,

Source§

type T = FloorSumData<R, X, Y>

type of operands: $T$
Source§

fn operate(a: &Self::T, b: &Self::T) -> Self::T

binary operaion: $\circ$
Source§

fn reverse_operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

fn operate_assign(x: &mut Self::T, y: &Self::T)

Source§

impl<R, const X: usize, const Y: usize> Unital for FloorSum<R, X, Y>
where R: SemiRing,

Source§

fn unit() -> Self::T

identity element: $e$
Source§

fn set_unit(x: &mut Self::T)

Auto Trait Implementations§

§

impl<R, const X: usize, const Y: usize> Freeze for FloorSum<R, X, Y>
where PhantomData<fn() -> R>: Freeze,

§

impl<R, const X: usize, const Y: usize> RefUnwindSafe for FloorSum<R, X, Y>
where PhantomData<fn() -> R>: RefUnwindSafe,

§

impl<R, const X: usize, const Y: usize> Send for FloorSum<R, X, Y>
where PhantomData<fn() -> R>: Send,

§

impl<R, const X: usize, const Y: usize> Sync for FloorSum<R, X, Y>
where PhantomData<fn() -> R>: Sync,

§

impl<R, const X: usize, const Y: usize> Unpin for FloorSum<R, X, Y>
where PhantomData<fn() -> R>: Unpin,

§

impl<R, const X: usize, const Y: usize> UnsafeUnpin for FloorSum<R, X, Y>
where PhantomData<fn() -> R>: UnsafeUnpin,

§

impl<R, const X: usize, const Y: usize> UnwindSafe for FloorSum<R, X, Y>
where PhantomData<fn() -> R>: 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> 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<M> Monoid for M
where M: SemiGroup + Unital,

Source§

fn pow<E>(x: Self::T, exp: E) -> Self::T
where E: ExpBits,

binary exponentiation: $x^n = x\circ\ddots\circ x$
Source§

fn fold<I>(iter: I) -> Self::T
where I: IntoIterator<Item = Self::T>,

Source§

impl<S> SemiGroup for S
where S: Magma + Associative,

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.