#include #include using namespace std; typedef long long ll; const ll kMOD = 1000 * 1000 * 1000 + 7; const int kMAX_T = 100010; const int kMAX_N = 1000010; int T; char query[100]; ll memo[kMAX_N * 2]; ll ModFactorial(ll n, ll mod) { if (memo[n] > 0) return memo[n]; ll res = 1; while (n > 1) { res = (res * n) % mod; n--; if (memo[n] > 0) { res = (res * memo[n]) % mod; break; } } return memo[n] = res; } ll ModPow(ll a, ll b, ll mod) { if (b == 0) return 1; else if (b % 2 == 0) { ll d = ModPow(a, b / 2, mod); return (d * d) % mod; } else { return (a * ModPow(a, b - 1, mod)) % mod; } } ll InverseElement(ll n, ll mod) { return ModPow(n, mod - 2, mod); } ll ModPermutation(ll n, ll r, ll mod) { if (n < r) return 0; return (ModFactorial(n, mod) * InverseElement(ModFactorial(n - r, mod), mod)) % mod; } ll ModCombination(ll n, ll r, ll mod) { if (n < r) return 0; r = min(r, n - r); return (ModPermutation(n, r, mod) * InverseElement(ModFactorial(r, mod), mod)) % mod; } ll ModHomogeneousProduct(ll n, ll r, ll mod) { if (n == 0 && r == 0) return 1; return ModCombination(n + r - 1, r, mod); } void Solve() { char c; int n, k; char buf[100]; sscanf(query, "%c(%d,%d%s", &c, &n, &k, buf); if (query[0] == 'C') { printf("%lld\n", ModCombination(n, k, kMOD)); } else if (query[0] == 'P') { printf("%lld\n", ModPermutation(n, k, kMOD)); } else { printf("%lld\n", ModHomogeneousProduct(n, k, kMOD)); } } int main() { // 先に階乗を計算しておく ll res = 1; for (int i = 0; i < kMAX_N * 2; i++) { if (i > 1) { res = (res * i) % kMOD; } memo[i] = res; } scanf("%d", &T); for (int i = 0; i < T; i++) { scanf("%s", query); Solve(); } return 0; }