from sequtils import map, mapIt from strutils import split, parseInt, parseFloat import macros macro unpack*(input: seq; count: static[int]): untyped = result = quote do: () when NimMinor <= 13: for i in 0.. 0 のとき count個分 unpack した結果の tuple を返す type UnselectableTypeError = object of Exception template input*(typ: typedesc; count: Natural = 0): untyped = let line = stdin.readLine.split when count == 0: when typ is int: line.map(parseInt) elif typ is float: line.map(parseFloat) elif typ is string: line else: raise newException(UnselectableTypeError, "You selected a type other than int, float or string") else: when typ is int: line.map(parseInt).unpack(count) elif typ is float: line.map(parseFloat).unpack(count) elif typ is string: line.unpack(count) else: raise newException(UnselectableTypeError, "You selected a type other than int, float or string") template inputs*(typ: typedesc; count = 0; rows = 1): untyped = (1..rows).mapIt(input(typ, count)) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # template secretEcho*(x: varargs[string, `$`]) = for v in x: stderr.write(v) echo "" template secretEcho*[T](x: seq[seq[T]]) = for v in x: secretEcho v # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # type ModComb* = ref object of RootObj modFacs: seq[int] modFacInvs: seq[int] MOD: int proc modPow(n, p, m: int): int = if p == 0: 1 elif p mod 2 == 0: let half = modPow(n, p div 2, m) half * half mod m else: n * modPow(n, p - 1, m) mod m proc newModComb*(MOD = 1_000_000_007; size = 10_000_000): ModComb = result = ModComb(modFacs: newSeq[int](size + 1), modFacInvs: newSeq[int](size + 1), MOD: MOD) result.modFacs[0] = 1 result.modFacInvs[0] = 1 for i in 1..size: result.modFacs[i] = result.modFacs[i - 1] * i mod MOD result.modFacInvs[size] = modPow(result.modFacs[size], MOD - 2, MOD) for i in countdown(size - 1, 0): result.modFacInvs[i] = result.modFacInvs[i + 1] * (i + 1) mod MOD proc C*(this: ModComb; n, r: int): int = if r < 0 or n < r: 0 else: this.modFacs[n] * (this.modFacInvs[r] * this.modFacInvs[n - r] mod this.MOD) mod this.MOD proc P*(this: ModComb; n, r: int): int = if r < 0 or n < r: 0 else: this.modFacs[n] * this.modFacInvs[n - r] mod this.MOD proc H*(this: ModComb; n, r: int): int = if r == 0: 1 elif n == 0: 0 else: this.C(n + r - 1, r) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # from strutils import join let T = input(int, 1) S = inputs(string, 1, T).map(proc (s: string): seq[string] = s.split({'(', ')', ','})) comb = newModComb() for s in S: let n = s[1].parseInt r = s[2].parseInt case s[0]: of "C": echo comb.C(n, r) of "P": echo comb.P(n, r) of "H": echo comb.H(n, r) else: discard