using System; using System.Collections.Generic; using System.Text; using System.Linq; class Program { public void Proc() { Reader.IsDebug = false; int queryCount = int.Parse(Reader.ReadLine()); for (int i = 0; i < queryCount; i++) { string inpt = Reader.ReadLine(); char queryType = inpt[0]; string[] tmp = inpt.Substring(1).Trim().Replace("(", "").Replace(")", "").Split(','); int num1 = int.Parse(tmp[0]); int num2 = int.Parse(tmp[1]); long ans = 0; if (queryType == 'C' && num1 > 0 && num2 > 0) { ans = this.QueryC(num1, num2); } else if (queryType == 'P' && num1 > 0 && num2 > 0) { ans = this.QueryC(num1, num2); long orderKumiawase = this.orderKumiawase(num2); ans = (ans * orderKumiawase) % modNum; } else if(num1 > 0 && num2 > 0) { ans = this.QueryH(num1, num2); } else if (num2 == 0) { ans = 1; } Console.WriteLine(ans); } } private long modNum = 1000000000 + 7; private long QueryC(int target, int remain) { if (!dic1.ContainsKey(target)) { dic1.Add(target, new Dictionary()); } if (dic1[target].ContainsKey(remain)) { return dic1[target][remain]; } long ans = 0; if (target == 0 || target < remain) { return 0; } if (target == remain) { return 1; } if (remain == 1) { return target; } ans = this.QueryC(target - 1, remain); ans += this.QueryC(target - 1, remain - 1); ans = ans % modNum; return ans; } private long orderKumiawase(long targetCnt) { if (dic2.ContainsKey(targetCnt)) { return dic2[targetCnt]; } if (targetCnt == 1) { return targetCnt; } long ans = 1; for (long i = 1; i <= targetCnt; i++) { if (dic2.ContainsKey(i)) { ans = dic2[i]; } else { ans *= i; ans = ans % modNum; dic2.Add(i, ans); } } return ans; } private long QueryH(int target, int remain) { if (!dic3.ContainsKey(target)) { dic3.Add(target, new Dictionary()); } if (dic3[target].ContainsKey(remain)) { return dic3[target][remain]; } if (target == 0) { return 0; } if (remain == 1) { return target; } long ans = 0; for (int i = target; i >= 1; i--) { ans += QueryH(i, remain - 1); } dic3[target].Add(remain, ans); return ans; } private Dictionary> dic1 = new Dictionary>(); private Dictionary dic2 = new Dictionary(); private Dictionary> dic3 = new Dictionary>(); public class Reader { public static bool IsDebug = true; private static String PlainInput = @" 5 C(1,1000000) C(0,0) P(1000000,1000000) P(1,10) H(1,1000) "; private static System.IO.StringReader Sr = null; public static string ReadLine() { if (IsDebug) { if (Sr == null) { Sr = new System.IO.StringReader(PlainInput.Trim()); } return Sr.ReadLine(); } else { return Console.ReadLine(); } } public static int[] GetInt(char delimiter = ' ', bool trim = false) { string inptStr = ReadLine(); if (trim) { inptStr = inptStr.Trim(); } string[] inpt = inptStr.Split(delimiter); int[] ret = new int[inpt.Length]; for (int i = 0; i < inpt.Length; i++) { ret[i] = int.Parse(inpt[i]); } return ret; } } static void Main() { Program prg = new Program(); prg.Proc(); } }