dsalgo 0.3.10

A package for Datastructures and Algorithms.
Documentation
use crate::{
    modular_factorial_table_usize::*,
    modular_inverse_factorial_table_usize::*,
};

pub struct FactorialTablesFrequentOps {
    pub p: usize,
    pub fact: Vec<usize>,
    pub inv_fact: Vec<usize>,
}

impl FactorialTablesFrequentOps {
    pub fn new(
        p: usize,
        size: usize,
    ) -> Self {
        let fact = factorial(p, size);

        let inv_fact = inverse_factorial(p, size);

        Self { p, fact, inv_fact }
    }

    pub fn p(
        &self,
        n: usize,
        k: usize,
    ) -> usize {
        if n < k {
            0
        } else {
            self.fact[n] * self.inv_fact[n - k] % self.p
        }
    }

    pub fn c(
        &self,
        n: usize,
        k: usize,
    ) -> usize {
        self.p(n, k) * self.inv_fact[k] % self.p
    }

    pub fn h(
        &self,
        n: usize,
        k: usize,
    ) -> usize {
        if n == 0 {
            0
        } else {
            self.c(n - 1 + k, k)
        }
    }

    pub fn inv(
        &self,
        n: usize,
    ) -> usize {
        self.fact[n - 1] * self.inv_fact[n] % self.p
    }

    pub fn inv_p(
        &self,
        n: usize,
        k: usize,
    ) -> usize {
        assert!(k <= n);

        self.inv_fact[n] * self.fact[n - k] % self.p
    }

    pub fn inv_c(
        &self,
        n: usize,
        k: usize,
    ) -> usize {
        self.inv_p(n, k) * self.fact[k] % self.p
    }
}

#[cfg(test)]

mod tests {

    use super::*;

    #[test]

    fn test() {
        let p = 1_000_000_007;

        let f = FactorialTablesFrequentOps::new(p, 100);

        assert_eq!(f.c(5, 2), 10);
    }
}