結果
問題 | No.980 Fibonacci Convolution Hard |
ユーザー | zer0-star |
提出日時 | 2021-10-13 20:18:01 |
言語 | Nim (2.0.2) |
結果 |
AC
|
実行時間 | 1,636 ms / 2,000 ms |
コード長 | 12,337 bytes |
コンパイル時間 | 3,456 ms |
コンパイル使用メモリ | 91,176 KB |
実行使用メモリ | 6,948 KB |
最終ジャッジ日時 | 2024-09-17 16:22:16 |
合計ジャッジ時間 | 33,500 ms |
ジャッジサーバーID (参考情報) |
judge6 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,566 ms
6,812 KB |
testcase_01 | AC | 1,555 ms
6,940 KB |
testcase_02 | AC | 1,571 ms
6,948 KB |
testcase_03 | AC | 1,537 ms
6,940 KB |
testcase_04 | AC | 1,537 ms
6,940 KB |
testcase_05 | AC | 1,546 ms
6,940 KB |
testcase_06 | AC | 1,562 ms
6,944 KB |
testcase_07 | AC | 1,566 ms
6,944 KB |
testcase_08 | AC | 1,557 ms
6,944 KB |
testcase_09 | AC | 1,567 ms
6,940 KB |
testcase_10 | AC | 1,636 ms
6,940 KB |
testcase_11 | AC | 1,563 ms
6,944 KB |
testcase_12 | AC | 1,556 ms
6,944 KB |
testcase_13 | AC | 1,578 ms
6,944 KB |
testcase_14 | AC | 1,544 ms
6,940 KB |
testcase_15 | AC | 1,569 ms
6,944 KB |
testcase_16 | AC | 1,421 ms
6,940 KB |
コンパイルメッセージ
/home/linuxbrew/.linuxbrew/Cellar/nim/2.0.2/nim/lib/pure/prelude.nim(28, 11) Warning: imported and not used: 'parseopt' [UnusedImport] /home/judge/data/code/Main.nim(17, 12) Warning: imported and not used: 'sugar' [UnusedImport] /home/linuxbrew/.linuxbrew/Cellar/nim/2.0.2/nim/lib/pure/prelude.nim(28, 11) Warning: imported and not used: 'strformat' [UnusedImport] /home/judge/data/code/Main.nim(15, 37) Warning: imported and not used: 'strformat' [UnusedImport] /home/linuxbrew/.linuxbrew/Cellar/nim/2.0.2/nim/lib/pure/prelude.nim(28, 11) Warning: imported and not used: 'hashes' [UnusedImport] /home/judge/data/code/Main.nim(15, 48) Warning: imported and not used: 'bitops' [UnusedImport]
ソースコード
# ========= utils/base.nim ========= {{{ when not declared(INCLUDE_GUARD_UTILS_BASE_NIM): const INCLUDE_GUARD_UTILS_BASE_NIM = 1 import macros macro Please(x): untyped = nnkStmtList.newTree() Please give me AC Please give me AC Please give me AC {.hints: off, checks: off, overflowChecks: on, checks: on.} include prelude import sequtils, math, algorithm, strformat, bitops, deques, heapqueue when (not (NimMajor <= 0)) or NimMinor >= 19: import sugar else: import future iterator range(x, y: int): int {.inline.} = var res = x while res < y: yield res inc(res) iterator range(x: int): int {.inline.} = var res = 0 while res < x: yield res inc(res) proc range(x, y: int): seq[int] {.inline.} = toSeq(x..y-1) proc range(x: int): seq[int] {.inline.} = toSeq(0..x-1) proc discardableId[T](x: T): T {.inline, discardable.} = return x macro `:=`(x, y: untyped): untyped = if (x.kind == nnkIdent): return quote do: when declaredInScope(`x`): `x` = `y` else: var `x` = `y` discardableId(`x`) else: return quote do: `x` = `y` discardableId(`x`) when NimMajor <= 0 and NimMinor <= 17: proc count[T](co: openArray[T]; obj: T): int = for itm in items(co): if itm == obj: inc result proc divmod(x, y: SomeInteger): (int, int) = (x div y, x mod y) proc `min=`[T](x: var T; y: T): bool {.discardable.} = if x > y: x = y return true else: return false proc `max=`[T](x: var T; y: T): bool {.discardable.} = if x < y: x = y return true else: return false when NimMajor <= 0 and NimMinor <= 17: iterator pairs(n: NimNode): (int, NimNode) {.inline.} = for i in 0 ..< n.len: yield (i, n[i]) #[ when NimMajor <= 0 and NimMinor <= 18: macro parseInnerType(x: NimNode): untyped = newIdentNode("parse" & x[1][1].repr) else: macro parseInnerType(x: typedesc): untyped = newIdentNode("parse" & x.getType[1][1].repr) ]# proc parseInnerType(x: NimNode): NimNode = newIdentNode("parse" & x[1].repr) proc inputAsTuple(ty: NimNode): NimNode = result = nnkStmtListExpr.newTree() t := genSym() result.add quote do: (let `t` = stdin.readLine.split) p := nnkPar.newTree() for i, typ_tmp in ty.pairs: var ece, typ: NimNode if typ_tmp.kind == nnkExprColonExpr: ece = nnkExprColonExpr.newTree(typ_tmp[0]) typ = typ_tmp[1] else: ece = nnkExprColonExpr.newTree(ident("f" & $i)) typ = typ_tmp if typ.repr == "string": ece.add quote do: `t`[`i`] else: parsefn := newIdentNode("parse" & typ.repr) ece.add quote do: `t`[`i`].`parsefn` p.add ece result.add p macro inputAsType(ty: untyped): untyped = if ty.kind == nnkBracketExpr: if ty[1].repr == "string": return quote do: stdin.readLine.split else: parsefn := parseInnerType(ty) return quote do: stdin.readLine.split.map(`parsefn`) #[ when NimMajor <= 0 and NimMinor <= 18: stdin.readLine.split.map(parseInnerType(ty.getType)) else: stdin.readLine.split.map(parseInnerType(ty)) ]# elif ty.kind == nnkPar: return inputAsTuple(ty) elif ty.repr == "string": return quote do: stdin.readLine else: parsefn := ident("parse" & ty.repr) return quote do: stdin.readLine.`parsefn` macro input(query: untyped): untyped = doAssert query.kind == nnkStmtList result = nnkStmtList.newTree() letSect := nnkVarSection.newTree() for defs in query: if defs[0].kind == nnkIdent: tmp := nnkIdentDefs.newTree(defs[0], newEmptyNode()) typ := defs[1][0] var val: NimNode if typ.len <= 2: val = quote do: inputAsType(`typ`) else: op := typ[2] typ.del(2, 1) val = quote do: inputAsType(`typ`).mapIt(`op`) if defs[1].len > 1: op := defs[1][1] it := ident"it" tmp.add quote do: block: var `it` = `val` `op` else: tmp.add val letSect.add tmp elif defs[0].kind == nnkPar: vt := nnkVarTuple.newTree() for id in defs[0]: vt.add id vt.add newEmptyNode() sle := nnkStmtListExpr.newTree() t := genSym() sle.add quote do: (let `t` = stdin.readLine.split) p := nnkPar.newTree() if defs[1][0].kind == nnkPar: for i, typ in defs[1][0].pairs: if typ.repr == "string": p.add quote do: `t`[`i`] else: parsefn := newIdentNode("parse" & typ.repr) p.add quote do: `t`[`i`].`parsefn` else: typ := defs[1][0] if typ.repr == "string": for i in 0..<defs[0].len: p.add quote do: `t`[`i`] else: parsefn := newIdentNode("parse" & typ.repr) for i in 0..<defs[0].len: p.add quote do: `t`[`i`].`parsefn` sle.add p vt.add sle letSect.add vt elif defs[0].kind == nnkBracketExpr: ids := nnkIdentDefs.newTree(defs[0][0], newEmptyNode()) cnt := defs[0][1] typ := defs[1][0] var input: NimNode if typ.kind == nnkBracketExpr and typ.len > 2: op := typ[2] typ.del(2, 1) input = quote do: inputAsType(`typ`).mapIt(`op`) else: input = quote do: inputAsType(`typ`) var val: NimNode if defs[0].len > 2: op := defs[0][2] it := ident"it" val = quote do: block: var `it` = `input` `op` else: val = input if defs[1].len > 1: op := defs[1][1] it := ident"it" ids.add(quote do: block: var `it` = newSeqWith(`cnt`, `val`) `op`) else: ids.add(quote do: newSeqWith(`cnt`, `val`)) letSect.add ids result.add letSect proc makeSeq[T, Idx](num: array[Idx, int]; init: T): auto = when num.len == 1: return newSeqWith(num[0], init) else: var tmp: array[num.len-1, int] for i, t in tmp.mpairs: t = num[i+1] return newSeqWith(num[0], makeSeq(tmp, init)) proc parseInt1(str: string): int = str.parseInt - 1 # ========= utils/base.nim ========= }}} # ========= math/modint.nim ========= {{{ # ========= math/mathMod.nim ========= {{{ when not declared(INCLUDE_GUARD_MATH_MATHMOD_NIM): const INCLUDE_GUARD_MATH_MATHMOD_NIM = 1 proc `mod`(x, y: int): int {.inline.} = if x < 0: y - system.`mod`(-x, y) else: system.`mod`(x, y) # ========= math/mathMod.nim ========= }}} when not declared(INCLUDE_GUARD_MATH_MODINT_NIM): const INCLUDE_GUARD_MATH_MODINT_NIM = 1 import math, sequtils import strutils proc extgcd(x, y: SomeInteger): (int, int) = if x < y: let (a, b) = extgcd(y, x) return (b, a) if y == 0 or x mod y == 0: return (0, 1) let (a, b) = extgcd(y, x mod y) return (b, -(x div y) * b + a) type ModInt[M: static[int]] = object v: int template initModInt(val: int): auto = when declared(MOD): ModInt[MOD](v: val mod MOD) else: ModInt[1000000007](v: val mod 1000000007) proc `$`[M](n: ModInt[M]): string {.inline.} = $n.v proc inv[M](n: ModInt[M]): ModInt[M] {.inline.} = result.v = (extgcd(n.v, M)[0]) mod M proc modinv(n: int; m: int): int {.inline.} = result = (extgcd(n, m)[0]) mod m proc `+`[M](n, m: ModInt[M]): ModInt[M] {.inline.} = result.v = (n.v + m.v) if result.v >= M: result.v -= M proc `+`[M](n: ModInt[M]; m: int): ModInt[M] {.inline.} = result.v = (n.v + m) mod M proc `*`[M](n, m: ModInt[M]): ModInt[M] {.inline.} = result.v = n.v * m.v mod M proc `*`[M](n: ModInt[M]; m: int): ModInt[M] {.inline.} = result.v = n.v * m mod M proc `-`[M](n: ModInt[M]): ModInt[M] {.inline.} = result.v = M - n.v proc `-`[M](n: ModInt[M]; m: int): ModInt[M] {.inline.} = result.v = (n.v - m) mod M proc `-`[M](n, m: ModInt[M]): ModInt[M] {.inline.} = result.v = (n.v - m.v) mod M proc `/`[M](n, m: ModInt[M]): ModInt[M] {.inline.} = n * inv(m) proc `/`[M](n: ModInt[M]; m: int): ModInt[M] {.inline.} = n / initModInt(m) proc `+=`[M](n: var ModInt[M]; m: int|ModInt[M]) {.inline.} = n = n + m proc `-=`[M](n: var ModInt[M]; m: int|ModInt[M]) {.inline.} = n = n - m proc `*=`[M](n: var ModInt[M]; m: int|ModInt[M]) {.inline.} = n = n * m proc `/=`[M](n: var ModInt[M]; m: int|ModInt[M]) {.inline.} = n = n / m proc fac[M](n: ModInt[M]): ModInt[M] = result.v = 1 for i in 2..n.v: result.v = result.v * i mod M proc perm[M](n, m: ModInt[M]): ModInt[M] = result.v = 1 for i in n.v-m.v+1..n.v: result.v = result.v * i mod M proc binom[M](n, m: ModInt[M]): ModInt[M] {.inline.} = perm(n, m) / (fac(m)) proc modfac(n: int; M: static[int]): int = result = 1 for i in 2..n: result = result * i mod M proc modperm(n, m: int; M: static[int]): int = result = 1 for i in n-m+1..n: result = result * i mod M proc modbinom(n, m: int; M: static[int]): int {.inline.} = modperm(n, m, M) / (modfac(m, M)) proc garner(args: openArray[(int, int)]; modulo = -1): (int, int) = result = (1, 0) let n = args.len var coe, con = newSeq[int](n) for c in coe.mitems: c = 1 for i in 0..<n: let t = (args[i][1] - con[i]) * modinv(coe[i], args[i][0]) mod args[i][0] for k in i+1 ..< n: con[k] = (con[k] + coe[k] * t) mod args[k][0] coe[k] = coe[k] * args[i][0] mod args[k][0] result[1] = result[1] + result[0] * t result[0] = result[0] * args[i][0] if modulo > 0: result[0] = result[0] mod modulo result[1] = result[1] mod modulo if modulo > 0: result[0] = modulo proc garner(args: openArray[(int, seq[int])]; modulo = -1): (int, seq[int]) = let P = args[0][1].len result = (1, newSeq[int](P)) let n = args.len var coe = newSeq[int](n) con = newSeqWith(n, newSeq[int](P)) for c in coe.mitems: c = 1 for i in 0..<n: for p in 0..<P: let t = (args[i][1][p] - con[i][p]) * modinv(coe[i], args[i][ 0]) mod args[i][0] for k in i+1 ..< n: con[k][p] = (con[k][p] + coe[k] * t mod args[k][0]) mod args[k][0] if modulo > 0: result[1][p] = (result[1][p] + result[0] * t mod modulo) mod modulo else: result[1][p] = (result[1][p] + result[0] * t) for k in i+1 ..< n: coe[k] = coe[k] * args[i][0] mod args[k][0] result[0] = result[0] * args[i][0] mod modulo if modulo > 0: result[0] = result[0] mod modulo if modulo > 0: result[0] = modulo proc modpow(n, p, m: int): int = var p = p t = n result = 1 while p > 0: if (p and 1) == 1: result = result * t mod m t = t * t mod m p = p shr 1 template parseModInt(x: string): ModInt = initModInt(x.parseInt) # ========= math/modint.nim ========= }}} input: P: int Q: int var p = newSeqWith(4, initModInt(0)) q = @[initModInt(1), initModInt(-2*P), initModInt(P^2-2), initModInt(2*P), initModInt(1)] p[2] += 1 proc solve[T](n: int; p, q: seq[T]): T = if n == 0: return p[0] var v = newSeqWith(q.len, initModInt(0)) u = newSeqWith(p.len, initModInt(0)) for i in 0..<q.len: for k in 0..2*i: if 2*i-k <= q.high and k <= q.high: v[i] += q[k] * q[2*i-k] * (if k mod 2 == 0: 1 else: -1) if n mod 2 == 0: for i in 0..<p.len: for k in 0..2*i: if 2*i-k <= p.high and k <= q.high: u[i] += q[k] * p[2*i-k] * (if k mod 2 == 0: 1 else: -1) else: for i in 0..<p.len: for k in 0..2*i+1: if 2*i+1-k <= p.high and k <= q.high: u[i] += q[k] * p[2*i+1-k] * (if k mod 2 == 0: 1 else: -1) return solve(n div 2, u, v) for i in range(Q): input: N: int echo solve(N-2, p, q)