use std::collections::HashMap; use std::io::*; use std::str::FromStr; use std::string::String; fn read() -> T { let stdin = stdin(); let stdin = stdin.lock(); let token: String = stdin .bytes() .map(|c| c.expect("failed to read char") as char) .skip_while(|c| c.is_whitespace()) .take_while(|c| !c.is_whitespace()) .collect(); token.parse().ok().expect("failed to parse token") } #[derive(Eq, PartialEq, Clone, Debug)] pub struct Rev(pub T); impl PartialOrd for Rev { fn partial_cmp(&self, other: &Rev) -> Option { other.0.partial_cmp(&self.0) } } impl Ord for Rev { fn cmp(&self, other: &Rev) -> std::cmp::Ordering { other.0.cmp(&self.0) } } fn lower_bound(vec: &Vec, x: T) -> usize { let (mut left, mut right): (i32, i32) = (-1, vec.len() as i32); while (right - left) > 1 { let mid = (right + left) / 2; if x <= vec[mid as usize] { right = mid; } else { left = mid; } } return right as usize; } fn upper_bound(vec: &Vec, x: T) -> usize { let (mut left, mut right): (i32, i32) = (-1, vec.len() as i32); while (right - left) > 1 { let mid = (right + left) / 2; if x < vec[mid as usize] { right = mid; } else { left = mid; } } return right as usize; } struct Combination { MOD: u64, fac: Vec, fac_inv: Vec, } impl Combination { pub fn new(n: u64) -> Self { let MOD: u64 = 1_000_000_007; let mut fac: Vec = vec![0; n as usize + 1]; let mut fac_inv: Vec = vec![0; n as usize + 1]; let get_inverse = |mut n: u64| -> u64 { let (mut res, mut p) = (1, MOD - 2); while p != 0 { if p & 1 == 1 { res = (res * n) % MOD; } n = (n * n) % MOD; p >>= 1; } return res; }; fac[0] = 1; for i in 1..n + 1 { fac[i as usize] = (fac[i as usize - 1] * i) % MOD; } for i in 0..n + 1 { fac_inv[i as usize] = get_inverse(fac[i as usize]); } Combination { MOD: MOD, fac: fac, fac_inv: fac_inv, } } fn get_comb(&self, n: u64, r: u64) -> u64 { if n < r { return 0; } let a: u64 = self.fac[n as usize]; let b: u64 = self.fac_inv[(n - r) as usize]; let c: u64 = self.fac_inv[r as usize]; let bc: u64 = (b * c) % self.MOD; return (a * bc) % self.MOD; } fn get_perm(&self, n: u64, r: u64) -> u64 { if n < r { return 0; } let a: u64 = self.fac[n as usize]; let b: u64 = self.fac_inv[(n - r) as usize]; return (a * b) % self.MOD; } fn get_dupc(&self, n: u64, r: u64) -> u64 { if n == 0 && r == 0 { return 1; } return self.get_comb(n + r - 1, r); } } fn main() { let t: u64 = read(); let comb = Combination::new(2_000_000); let ans: Vec = (0..t) .map(|_| { let mut input: String = read(); let com = input.remove(0); input.pop(); input.remove(0); let vec = input.split(',').collect::>(); let (n, r): (u64, u64) = (vec[0].parse().unwrap(), vec[1].parse().unwrap()); if com == 'C' { return comb.get_comb(n, r); } else if com == 'P' { return comb.get_perm(n, r); } else { return comb.get_dupc(n, r); } }) .collect(); for x in ans { println!("{}", x); } }