pub fn crt_slice<T>(
        a: &[ModInt<T, ModDyn<T>>],
        b: &[ModInt<T, ModDyn<T>>],
    ) -> Vec<Option<ModInt<T, ModDyn<T>>>>
    where
        T: PrimInt + Unsigned + NumAssignOps,
    {
        let mut result = vec![];
        if a.len() == 0 || a.len() != b.len() {
            return result;
        }
        // Now a.len() == b.len() >= 1
        result.reserve(a.len());
        let m = a[0].modulus();
        let mm = b[0].modulus();
        if m == mm {
            for i in 0..a.len() {
                if a[i].value() == b[i].value() {
                    result.push(Some(a[i]));
                } else {
                    result.push(None);
                }
            }
        } else if m > mm {
            return crt_slice(b, a);
        } else {
            // m < mm
            let (dmm, xmm) = inv_gcd(ModInt::new_with(m, mm));
            let d = dmm.value();
            debug_assert!(d == gcd(m, mm));
            let x = xmm.value();
            for i in 0..a.len() {
                result.push(crt_internal(a[i].value(), b[i].value(), m, mm, d, x));
                // if let Some(cmmm) = crt_internal(a[i].value(), b[i].value(), m, mm, d, x) {
                //     result.push(cmmm);
                // } else {
                //     return None;
                // }
            }
        }
        return result;
    }
// Two-slice Chinese remainder theorem function
// It assumes all the moduli are equal for each slice
Two-slice Chinese remainder theorem function
It assumes all the moduli are equal for each slice
Two - slice Chinese remainder theorem function It assumes all the moduli are equal for each slice
pub fn crt_slice<T>(
        a: &[ModInt<T, ModDyn<T>>],
        b: &[ModInt<T, ModDyn<T>>],
    ) -> Vec<Option<ModInt<T, ModDyn<T>>>>
    where
        T: PrimInt + Unsigned + NumAssignOps,
    {
        let mut result = vec![];
        if a.len() == 0 || a.len() != b.len() {
            return result;
        }
        // Now a.len() == b.len() >= 1
        result.reserve(a.len());
        let m = a[0].modulus();
        let mm = b[0].modulus();
        if m == mm {
            for i in 0..a.len() {
                if a[i].value() == b[i].value() {
                    result.push(Some(a[i]));
                } else {
                    result.push(None);
                }
            }
        } else if m > mm {
            return crt_slice(b, a);
        } else {
            // m < mm
            let (dmm, xmm) = inv_gcd(ModInt::new_with(m, mm));
            let d = dmm.value();
            debug_assert!(d == gcd(m, mm));
            let x = xmm.value();
            for i in 0..a.len() {
                result.push(crt_internal(a[i].value(), b[i].value(), m, mm, d, x));
                // if let Some(cmmm) = crt_internal(a[i].value(), b[i].value(), m, mm, d, x) {
                //     result.push(cmmm);
                // } else {
                //     return None;
                // }
            }
        }
        return result;
    }
pub fn crt_slice < T > ( a : & [ ModInt < T , ModDyn < T > > ] , b : & [ ModInt < T , ModDyn < T > > ] , ) -> Vec < Option < ModInt < T , ModDyn < T > > > > where T : PrimInt + Unsigned + NumAssignOps , { let mut result = vec ! [ ] ; if a . len ( ) == 0 || a . len ( ) != b . len ( ) { return result ; } // Now a.len() == b.len() >= 1 result . reserve ( a . len ( ) ) ; let m = a [ 0 ] . modulus ( ) ; let mm = b [ 0 ] . modulus ( ) ; if m == mm { for i in 0 .. a . len ( ) { if a [ i ] . value ( ) == b [ i ] . value ( ) { result . push ( Some ( a [ i ] ) ) ; } else { result . push ( None ) ; } } } else if m > mm { return crt_slice ( b , a ) ; } else { // m < mm let ( dmm , xmm ) = inv_gcd ( ModInt :: new_with ( m , mm ) ) ; let d = dmm . value ( ) ; debug_assert ! ( d gcd ( m mm ) ) ; let x = xmm . value ( ) ; for i in 0 .. a . len ( ) { result . push ( crt_internal ( a [ i ] . value ( ) , b [ i ] . value ( ) , m , mm , d , x ) ) ; // if let Some(cmmm) = crt_internal(a[i].value(), b[i].value(), m, mm, d, x) { //     result.push(cmmm); // } else { //     return None; // } } } return result ; }
Two-slice Chinese remainder theorem function
It assumes all the moduli are equal for each slice
Two - slice Chinese remainder theorem function It assumes all the moduli are equal for each slice
a
&[ModInt<T, ModDyn<T>>]
b
&[ModInt<T, ModDyn<T>>]
a
&[ModInt<T, ModDyn<T>>]
b
&[ModInt<T, ModDyn<T>>]