dsalgo 0.3.10

A package for Datastructures and Algorithms.
Documentation
use std::ops::*;

pub fn number_of_common_subsequences<N, T: Eq>(
    a: &[T],
    b: &[T],
) -> N
where
    N: From<i32> + Clone + Sub<Output = N> + Add<Output = N>,
{
    let n = a.len();

    let m = b.len();

    if n < m {
        return number_of_common_subsequences::<N, _>(b, a);
    }

    let mut dp: Vec<N> = vec![1.into(); m + 1];

    for i in 0..n {
        for j in (0..m).rev() {
            if a[i] != b[j] {
                dp[j + 1] = dp[j + 1].clone() - dp[j].clone();
            }
        }

        for j in 0..m {
            dp[j + 1] = dp[j + 1].clone() + dp[j].clone();
        }
    }

    dp[m].clone()
}

#[cfg(test)]

mod tests {

    use super::*;

    #[test]

    fn test() {
        let cases = vec![
            ((vec![1, 3], vec![3, 1]), 3),
            ((vec![1, 1], vec![1, 1]), 6),
            ((vec![3, 4, 5, 6], vec![3, 4, 5, 6]), 16),
            (
                (
                    vec![9, 6, 5, 7, 5, 9, 8, 5, 6, 7],
                    vec![8, 6, 8, 5, 5, 7, 9, 9, 7],
                ),
                191,
            ),
            (
                (
                    vec![
                        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                        1, 1,
                    ],
                    vec![
                        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                        1, 1,
                    ],
                ),
                846527861,
            ),
        ];

        use crate::const_generics_modular_int_i64::Modint;

        const MOD: i64 = 1_000_000_007;

        type Mint = Modint<MOD>;

        for ((a, b), ans) in cases {
            assert_eq!(
                number_of_common_subsequences::<Mint, i32>(&a, &b),
                ans.into()
            );
        }
    }
}