結果

問題 No.2770 Coupon Optimization
ユーザー 👑 seekworserseekworser
提出日時 2024-05-31 22:10:59
言語 Nim
(2.2.0)
結果
AC  
実行時間 559 ms / 3,000 ms
コード長 32,174 bytes
コンパイル時間 6,991 ms
コンパイル使用メモリ 113,424 KB
実行使用メモリ 37,312 KB
最終ジャッジ日時 2024-12-20 23:43:05
合計ジャッジ時間 15,279 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 16
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

import macros;macro ImportExpand(s:untyped):untyped = parseStmt($s[2])
# {.checks: off.}
ImportExpand "cplib/tmpl/citrus.nim" <=== "when not declared CPLIB_TMPL_CITRUS:\n const CPLIB_TMPL_CITRUS* = 1\n {.warning[UnusedImport]: off
    .}\n {.hint[XDeclaredButNotUsed]: off.}\n import os\n import algorithm\n import sequtils\n import tables\n import macros\n
    import std/math\n import sets\n import strutils\n import strformat\n import sugar\n import streams\n import deques\n import
    bitops\n import heapqueue\n import options\n import hashes\n const MODINT998244353* = 998244353\n const MODINT1000000007* =
    1000000007\n #[ include cplib/utils/infl ]#\n when not declared CPLIB_UTILS_INFL:\n const CPLIB_UTILS_INFL* = 1\n const INFi32
    * = 100100111.int32\n const INFL* = int(3300300300300300491)\n type double* = float64\n let readNext = iterator(getsChar: bool =
    false): string {.closure.} =\n while true:\n var si: string\n try: si = stdin.readLine\n except EOFError:
    yield \"\"\n for s in si.split:\n if getsChar:\n for i in 0..<s.len():\n yield
    s[i..i]\n else:\n if s.isEmptyOrWhitespace: continue\n yield s\n proc input*(t:
    typedesc[string]): string = readNext()\n proc input*(t: typedesc[char]): char = readNext(true)[0]\n proc input*(t: typedesc[int]): int =
    readNext().parseInt\n proc input*(t: typedesc[float]): float = readNext().parseFloat\n macro input*(t: typedesc, n: varargs[int]): untyped
    =\n var repStr = \"\"\n for arg in n:\n repStr &= &\"({arg.repr}).newSeqWith \"\n parseExpr(&\"{repStr}input({t}
    )\")\n macro input*(ts: varargs[auto]): untyped =\n var tupStr = \"\"\n for t in ts:\n tupStr &= &\"input({t.repr}
    ),\"\n parseExpr(&\"({tupStr})\")\n macro input*(n: int, ts: varargs[auto]): untyped =\n for typ in ts:\n if typ
    .typeKind != ntyAnything:\n error(\"Expected typedesc, got \" & typ.repr, typ)\n parseExpr(&\"({n.repr}).newSeqWith input
    ({ts.repr})\")\n proc `fmtprint`*(x: int or string or char or bool): string = return $x\n proc `fmtprint`*(x: float or float32 or float64):
    string = return &\"{x:.16f}\"\n proc `fmtprint`*[T](x: seq[T] or Deque[T] or HashSet[T] or set[T]): string = return x.toSeq.join(\" \")\n
    proc `fmtprint`*[T, N](x: array[T, N]): string = return x.toSeq.join(\" \")\n proc `fmtprint`*[T](x: HeapQueue[T]): string =\n var q =
    x\n while q.len != 0:\n result &= &\"{q.pop()}\"\n if q.len != 0: result &= \" \"\n proc `fmtprint`*[T](x:
    CountTable[T]): string =\n result = x.pairs.toSeq.mapIt(&\"{it[0]}: {it[1]}\").join(\" \")\n proc `fmtprint`*[K, V](x: Table[K, V]):
    string =\n result = x.pairs.toSeq.mapIt(&\"{it[0]}: {it[1]}\").join(\" \")\n proc print*(prop: tuple[f: File, sepc: string, endc: string
    , flush: bool], args: varargs[string, `fmtprint`]) =\n for i in 0..<len(args):\n prop.f.write(&\"{args[i]}\")\n if i
    != len(args) - 1: prop.f.write(prop.sepc) else: prop.f.write(prop.endc)\n if prop.flush: prop.f.flushFile()\n proc print*(args:
    varargs[string, `fmtprint`]) = print((f: stdout, sepc: \" \", endc: \"\\n\", flush: false), args)\n const LOCAL_DEBUG{.booldefine.} = false\n
     macro getSymbolName(x: typed): string = x.toStrLit\n macro debug*(args: varargs[untyped]): untyped =\n when LOCAL_DEBUG:\n
    result = newNimNode(nnkStmtList, args)\n template prop(e: string = \"\"): untyped = (f: stderr, sepc: \"\", endc: e, flush: true)\n
     for i, arg in args:\n if arg.kind == nnkStrLit:\n result.add(quote do: print(prop(), \"\\\"\", `arg`,
    \"\\\"\"))\n else:\n result.add(quote do: print(prop(\": \"), getSymbolName(`arg`)))\n result
    .add(quote do: print(prop(), `arg`))\n if i != args.len - 1: result.add(quote do: print(prop(), \", \"))\n else:
    result.add(quote do: print(prop(), \"\\n\"))\n else:\n return (quote do: discard)\n proc `%`*(x: SomeInteger, y: SomeInteger
    ): int =\n result = x mod y\n if y > 0 and result < 0: result += y\n if y < 0 and result > 0: result += y\n proc `//`*(x:
    SomeInteger, y: SomeInteger): int =\n result = x div y\n if y > 0 and result * y > x: result -= 1\n if y < 0 and result * y <
    x: result -= 1\n proc `^`*(x: SomeInteger, y: SomeInteger): int = x xor y\n proc `&`*(x: SomeInteger, y: SomeInteger): int = x and y\n
    proc `|`*(x: SomeInteger, y: SomeInteger): int = x or y\n proc `>>`*(x: SomeInteger, y: SomeInteger): int = x shr y\n proc `<<`*(x:
    SomeInteger, y: SomeInteger): int = x shl y\n proc `%=`*(x: var SomeInteger, y: SomeInteger): void = x = x % y\n proc `//=`*(x: var
    SomeInteger, y: SomeInteger): void = x = x // y\n proc `^=`*(x: var SomeInteger, y: SomeInteger): void = x = x ^ y\n proc `&=`*(x: var
    SomeInteger, y: SomeInteger): void = x = x & y\n proc `|=`*(x: var SomeInteger, y: SomeInteger): void = x = x | y\n proc `>>=`*(x: var
    SomeInteger, y: SomeInteger): void = x = x >> y\n proc `<<=`*(x: var SomeInteger, y: SomeInteger): void = x = x << y\n proc `[]`*(x, n: int
    ): bool = (x and (1 shl n)) != 0\n proc `[]=`*(x: var int, n: int, i: bool) =\n if i: x = x or (1 << n)\n else: (if x[n]: x = x
    xor (1 << n))\n proc pow*(a, n: int, m = INFL): int =\n var\n rev = 1\n a = a\n n = n\n while n
    > 0:\n if n % 2 != 0: rev = (rev * a) mod m\n if n > 1: a = (a * a) mod m\n n >>= 1\n return rev\n #[
    include cplib/math/isqrt ]#\n when not declared CPLIB_MATH_ISQRT:\n const CPLIB_MATH_ISQRT* = 1\n proc isqrt*(n: int): int =\n
     var x = n\n var y = (x + 1) shr 1\n while y < x:\n x = y\n y = (x + n div x) shr 1\n
     return x\n proc chmax*[T](x: var T, y: T): bool {.discardable.} = (if x < y: (x = y; return true; ) return false)\n proc chmin
    *[T](x: var T, y: T): bool {.discardable.} = (if x > y: (x = y; return true; ) return false)\n proc `max=`*[T](x: var T, y: T) = x = max(x, y
    )\n proc `min=`*[T](x: var T, y: T) = x = min(x, y)\n proc at*(x: char, a = '0'): int = int(x) - int(a)\n proc Yes*(b: bool = true): void
    = print(if b: \"Yes\" else: \"No\")\n proc No*(b: bool = true): void = Yes(not b)\n proc YES_upper*(b: bool = true): void = print(if b:
    \"YES\" else: \"NO\")\n proc NO_upper*(b: bool = true): void = Yes_upper(not b)\n const DXY* = [(0, -1), (0, 1), (-1, 0), (1, 0)]\n const
    DDXY* = [(1, -1), (1, 0), (1, 1), (0, -1), (0, 1), (-1, -1), (-1, 0), (-1, 1)]\n macro exit*(statement: untyped): untyped = (quote do:
    (`statement`; quit()))\n proc initHashSet[T](): Hashset[T] = initHashSet[T](0)\n"
ImportExpand "atcoder/convolution.nim" <=== "when not declared ATCODER_CONVOLUTION_HPP:\n const ATCODER_CONVOLUTION_HPP* = 1\n\n import std/math\n
    import std/sequtils\n import std/sugar\n #[ import atcoder/internal_math ]#\n when not declared ATCODER_INTERNAL_MATH_HPP:\n const
    ATCODER_INTERNAL_MATH_HPP* = 1\n import std/math\n \n # Fast moduler by barrett reduction\n # Reference: https:#en.wikipedia.org/wiki
    /Barrett_reduction\n # NOTE: reconsider after Ice Lake\n type Barrett* = object\n m*, im*:uint\n \n # @param m `1 <= m`\n proc
    initBarrett*(m:uint):auto = Barrett(m:m, im:cast[uint](-1) div m + 1)\n \n # @return m\n proc umod*(self: Barrett):uint =\n self.m\n
    \n {.emit: \"\"\"\n #include<cstdio>\n inline unsigned long long calc_mul(const unsigned long long &a, const unsigned long long &b){\n
    return (unsigned long long)(((unsigned __int128)(a)*b) >> 64);\n }\n \"\"\".}\n proc calc_mul*(a,b:culonglong):culonglong {.importcpp:
    \"calc_mul(#,#)\", nodecl, inline.}\n # @param a `0 <= a < m`\n # @param b `0 <= b < m`\n # @return `a * b % m`\n proc quo*(self:
    Barrett, n:int | uint):int =\n let n = n.uint\n let x = calc_mul(n.culonglong, self.im.culonglong).uint\n let r = n - x * self.m\n
     return int(if self.m <= r: x - 1 else: x)\n proc rem*(self: Barrett, n:int | uint):int =\n let n = n.uint\n let x = calc_mul(n
    .culonglong, self.im.culonglong).uint\n let r = n - x * self.m\n return int(if self.m <= r: r + self.m else: r)\n proc quorem*(self:
    Barrett, n:int | uint):(int, int) =\n let n = n.uint\n let x = calc_mul(n.culonglong, self.im.culonglong).uint\n let r = n - x *
    self.m\n return if self.m <= r: (int(x - 1), int(r + self.m)) else: (int(x), int(r))\n \n proc pow*(self: Barrett, n:uint | int, p:int
    ):int =\n var\n a = self.rem(n)\n r:uint = if self.m == 1: 0 else: 1\n p = p\n while p > 0:\n if (p and 1) !
    = 0: r = self.mul(r, a.uint)\n a = self.mul(a.uint, a.uint).int\n p = p shr 1\n return int(r)\n \n proc mul*(self: Barrett,
    a:uint, b:uint):uint {.inline.} =\n # [1] m = 1\n # a = b = im = 0, so okay\n \n # [2] m >= 2\n # im = ceil(2^64 / m)\n
    # -> im * m = 2^64 + r (0 <= r < m)\n # let z = a*b = c*m + d (0 <= c, d < m)\n # a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 +
    c*r + d*im\n # c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2\n # ((ab * im) >> 64) == c or c + 1\n
     let z = a * b\n # #ifdef _MSC_VER\n # unsigned long long x;\n # _umul128(z, im, &x);\n # #else\n ##TODO\n
     # unsigned long long x =\n # (unsigned long long)(((unsigned __int128)(z)*im) >> 64);\n # #endif\n #let x =
    calc_mul(z.culonglong, self.im.culonglong).uint\n #result = z - x * self.m\n #if self.m <= result: result += self.m\n return self
    .rem(z).uint\n \n # @param n `0 <= n`\n # @param m `1 <= m`\n # @return `(x ** n) % m`\n proc pow_mod_constexpr*(x, n, m:int):int =\n
     if m == 1: return 0\n var\n r = 1\n y = floorMod(x, m)\n n = n\n while n != 0:\n if (n and 1) != 0: r =
    (r * y) mod m\n y = (y * y) mod m\n n = n shr 1\n return r.int\n \n # Reference:\n # M. Forisek and J. Jancina,\n #
    Fast Primality Testing for Integers That Fit into a Machine Word\n # @param n `0 <= n`\n proc is_prime_constexpr*(n:int):bool =\n if n
    <= 1: return false\n if n == 2 or n == 7 or n == 61: return true\n if n mod 2 == 0: return false\n var d = n - 1\n while d mod
    2 == 0: d = d div 2\n for a in [2, 7, 61]:\n var\n t = d\n y = pow_mod_constexpr(a, t, n)\n while t != n - 1
    and y != 1 and y != n - 1:\n y = y * y mod n\n t = t shl 1\n if y != n - 1 and t mod 2 == 0:\n return false\n
     return true\n proc is_prime*[n:static[int]]():bool = is_prime_constexpr(n)\n # \n # # @param b `1 <= b`\n # # @return pair(g, x) s.t.
    g = gcd(a, b), xa = g (mod b), 0 <= x < b/g\n proc inv_gcd*(a, b:int):(int,int) =\n var a = floorMod(a, b)\n if a == 0: return (b, 0
    )\n \n # Contracts:\n # [1] s - m0 * a = 0 (mod b)\n # [2] t - m1 * a = 0 (mod b)\n # [3] s * |m1| + t * |m0| <= b\n
    var\n s = b\n t = a\n m0 = 0\n m1 = 1\n \n while t != 0:\n var u = s div t\n s -= t * u;\n
     m0 -= m1 * u; # |m1 * u| <= |m1| * s <= b\n \n # [3]:\n # (s - t * u) * |m1| + t * |m0 - m1 * u|\n # <= s * |m1| - t *
    u * |m1| + t * (|m0| + |m1| * u)\n # = s * |m1| + t * |m0| <= b\n \n var tmp = s\n s = t;t = tmp;\n tmp = m0;m0 =
    m1;m1 = tmp;\n # by [3]: |m0| <= b/g\n # by g != b: |m0| < b/g\n if m0 < 0: m0 += b div s\n return (s, m0)\n \n # Compile
    time primitive root\n # @param m must be prime\n # @return primitive root (and minimum in now)\n proc primitive_root_constexpr*(m:int
    ):int =\n if m == 2: return 1\n if m == 167772161: return 3\n if m == 469762049: return 3\n if m == 754974721: return 11\n
     if m == 998244353: return 3\n var divs:array[20, int]\n divs[0] = 2\n var cnt = 1\n var x = (m - 1) div 2\n while x mod
    2 == 0: x = x div 2\n var i = 3\n while i * i <= x:\n if x mod i == 0:\n divs[cnt] = i\n cnt.inc\n
    while x mod i == 0:\n x = x div i\n i += 2\n if x > 1:\n divs[cnt] = x\n cnt.inc\n var g = 2\n
    while true:\n var ok = true\n for i in 0..<cnt:\n if pow_mod_constexpr(g, (m - 1) div divs[i], m) == 1:\n ok =
    false\n break\n if ok: return g\n g.inc\n proc primitive_root*[m:static[int]]():auto =\n primitive_root_constexpr
    (m)\n \n # @param n `n < 2^32`\n # @param m `1 <= m < 2^32`\n # @return sum_{i=0}^{n-1} floor((ai + b) / m) (mod 2^64)\n proc
    floor_sum_unsigned*(n, m, a, b:uint):uint =\n result = 0\n var (n, m, a, b) = (n, m, a, b)\n while true:\n if a >= m:\n
     result += n * (n - 1) div 2 * (a div m)\n a = a mod m\n if b >= m:\n result += n * (b div m)\n b = b mod
    m\n \n let y_max = a * n + b\n if y_max < m: break\n # y_max < m * (n + 1)\n # floor(y_max / m) <= n\n n =
    y_max div m\n b = y_max mod m\n swap(m, a)\n #[ import atcoder/internal_bit ]#\n when not declared ATCODER_INTERNAL_BITOP_HPP:\n
     const ATCODER_INTERNAL_BITOP_HPP* = 1\n import std/bitops\n \n #ifdef _MSC_VER\n #include <intrin.h>\n #endif\n \n # @param n `0 <=
    n`\n # @return minimum non-negative `x` s.t. `n <= 2**x`\n proc ceil_pow2*(n:SomeInteger):int =\n var x = 0\n while (1.uint shl x) <
    n.uint: x.inc\n return x\n # @param n `1 <= n`\n # @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`\n proc bsf*(n:SomeInteger
    ):int =\n return countTrailingZeroBits(n)\n #[ import atcoder/element_concepts ]#\n when not declared ATCODER_ELEMENT_CONCEPTS_HPP:\n
    const ATCODER_ELEMENT_CONCEPTS_HPP* = 1\n proc inv*[T:SomeFloat](a:T):auto = T(1) / a\n proc init*(self:typedesc[SomeFloat], a:SomeNumber
    ):auto = self(a)\n type AdditiveGroupElem* = concept x, y, type T\n x + y\n x - y\n -x\n T(0)\n type
    MultiplicativeGroupElem* = concept x, y, type T\n x * y\n x / y\n # x.inv()\n T(1)\n type RingElem* = concept x, y, type T\n
     x + y\n x - y\n -x\n x * y\n T(0)\n T(1)\n type FieldElem* = concept x, y, type T\n x + y\n x - y\n
     x * y\n x / y\n -x\n # x.inv()\n T(0)\n T(1)\n type FiniteFieldElem* = concept x, type T\n T is FieldElem\n
     T.mod\n T.mod() is int\n x.pow(1000000)\n type hasInf* = concept x, type T\n T(Inf)\n\n type fft_info*[mint:FiniteFieldElem; g
    , rank2:static[int]] = object\n root, iroot: array[rank2 + 1, mint]\n rate2, irate2: array[max(0, rank2 - 2 + 1), mint]\n rate3, irate3:
    array[max(0, rank2 - 3 + 1), mint]\n\n proc initFFTInfo*[mint:FiniteFieldElem]():auto =\n const g = primitive_root[mint.mod]()\n const
    rank2 = bsf(mint.mod - 1)\n var root, iroot:array[rank2 + 1, mint]\n var rate2, irate2: array[max(0, rank2 - 2 + 1), mint]\n var rate3,
    irate3: array[max(0, rank2 - 3 + 1), mint]\n mixin init, inv\n\n root[rank2] = mint.init(g).pow((mint.mod - 1) shr rank2)\n iroot[rank2]
    = root[rank2].inv()\n for i in countdown(rank2 - 1, 0):\n root[i] = root[i + 1] * root[i + 1];\n iroot[i] = iroot[i + 1] * iroot[i +
    1];\n \n block:\n var\n prod = mint.init(1)\n iprod = mint.init(1)\n for i in 0..rank2 - 2:\n rate2[i] = root[i
    + 2] * prod\n irate2[i] = iroot[i + 2] * iprod\n prod *= iroot[i + 2]\n iprod *= root[i + 2]\n block:\n var\n
    prod = mint.init(1)\n iprod = mint.init(1)\n for i in 0..rank2 - 3:\n rate3[i] = root[i + 3] * prod;\n irate3[i] =
    iroot[i + 3] * iprod;\n prod *= iroot[i + 3];\n iprod *= root[i + 3];\n return fft_info[mint, g, rank2](root:root, iroot:iroot,
    rate2:rate2, irate2:irate2, rate3: rate3, irate3:irate3)\n \n proc butterfly*[mint:FiniteFieldElem](a:var seq[mint]) =\n mixin init\n let
    n = a.len\n let h = ceil_pow2(n)\n\n const info = initFFTInfo[mint]()\n\n var len = 0 # a[i, i+(n>>len), i+2*(n>>len), ..] is
    transformed\n while len < h:\n if h - len == 1:\n let p = 1 shl (h - len - 1)\n var rot = mint.init(1)\n for s in 0
    ..<(1 shl len):\n var offset = s shl (h - len)\n for i in 0..<p:\n let l = a[i + offset]\n let r = a[i +
    offset + p] * rot\n a[i + offset] = l + r\n a[i + offset + p] = l - r\n if s + 1 != (1 shl len):\n rot
    *= info.rate2[bsf(not s.uint)]\n len.inc\n else:\n # 4-base\n let p = 1 shl (h - len - 2)\n var\n rot =
    mint.init(1)\n imag = info.root[2]\n for s in 0..<(1 shl len):\n let\n rot2 = rot * rot\n rot3 =
    rot2 * rot\n offset = s shl (h - len)\n for i in 0..<p:\n let\n mod2 = (mint.mod() * mint.mod
    ()).uint\n a0 = (a[i + offset].val()).uint\n a1 = (a[i + offset + p].val() * rot.val()).uint\n a2 = (a[i +
    offset + 2 * p].val() * rot2.val()).uint\n a3 = (a[i + offset + 3 * p].val() * rot3.val()).uint\n a1na3imag = (mint.init
    (a1 + mod2 - a3).val() * imag.val()).uint\n na2 = mod2 - a2\n a[i + offset] = mint.init(a0 + a2 + a1 + a3)\n
    a[i + offset + 1 * p] = mint.init(a0 + a2 + (2.uint * mod2 - (a1 + a3)))\n a[i + offset + 2 * p] = mint.init(a0 + na2 + a1na3imag)\n
     a[i + offset + 3 * p] = mint.init(a0 + na2 + (mod2 - a1na3imag))\n if s + 1 != (1 shl len):\n rot *= info.rate3[bsf
    (not s.uint)]\n len += 2\n \n proc butterfly_inv*[mint:FiniteFieldElem](a:var seq[mint]) =\n let n = a.len\n let h = ceilpow2(n)\n
     mixin init\n\n const info = initFFTInfo[mint]()\n \n var len = h; # a[i, i+(n>>len), i+2*(n>>len), ..] is transformed\n while len >
    0:\n if len == 1:\n let p = 1 shl (h - len)\n var irot = mint.init(1)\n for s in 0..<(1 shl (len - 1)):\n let
    offset = s shl (h - len + 1)\n for i in 0..<p:\n let\n l = a[i + offset]\n r = a[i + offset + p]\n
     a[i + offset] = l + r\n a[i + offset + p] = mint.init((mint.mod() + l.val() - r.val()) * irot.val())\n if s + 1 !=
    (1 shl (len - 1)):\n irot *= info.irate2[bsf(not s.uint)]\n len.dec\n else:\n # 4-base\n let p = 1 shl (h -
    len);\n var irot = mint.init(1)\n let iimag = info.iroot[2]\n for s in 0..<(1 shl (len - 2)):\n let\n
    irot2 = irot * irot\n irot3 = irot2 * irot\n offset = s shl (h - len + 2)\n for i in 0..<p:\n let\n
     a0 = a[i + offset + 0 * p].val().uint\n a1 = a[i + offset + 1 * p].val().uint\n a2 = a[i + offset + 2 * p].val
    ().uint\n a3 = a[i + offset + 3 * p].val().uint\n a2na3iimag = mint.init((mint.mod.uint + a2 - a3) * iimag.val().uint
    ).val().uint\n \n a[i + offset] = mint.init(a0 + a1 + a2 + a3)\n a[i + offset + 1 * p] = mint.init((a0 + (mint.mod().uint -
    a1) + a2na3iimag) * irot.val().uint)\n a[i + offset + 2 * p] = mint.init((a0 + a1 + (mint.mod().uint - a2) + (mint.mod().uint - a3)) *
    irot2.val().uint)\n a[i + offset + 3 * p] = mint.init((a0 + (mint.mod().uint - a1) + (mint.mod().uint - a2na3iimag)) * irot3.val().uint
    )\n if s + 1 != (1 shl (len - 2)):\n irot *= info.irate3[bsf(not s.uint)]\n len -= 2\n\n proc convolution_naive*[mint
    :FiniteFieldElem](a, b:seq[mint]):seq[mint] =\n mixin `+=`\n let (n, m) = (a.len, b.len)\n result = newSeq[mint](n + m - 1)\n if n < m
    :\n for j in 0..<m:\n for i in 0..<n:\n result[i + j] += a[i] * b[j]\n else:\n for i in 0..<n:\n for j in 0
    ..<m:\n result[i + j] += a[i] * b[j]\n\n proc convolution_fft*[mint:FiniteFieldElem](a, b:seq[mint]):seq[mint] =\n mixin init, inv\n
     let\n (n, m) = (a.len, b.len)\n z = 1 shl ceil_pow2(n + m - 1)\n var (a, b) = (a, b)\n a.setLen(z)\n butterfly(a)\n b
    .setLen(z)\n butterfly(b)\n for i in 0..<z:\n a[i] *= b[i];\n butterfly_inv(a)\n a.setLen(n + m - 1)\n let iz = mint.init(z
    ).inv()\n for i in 0..<n + m - 1: a[i] *= iz\n return a\n\n proc convolution*[mint:FiniteFieldElem](a, b:seq[mint]):seq[mint] =\n let (n
    , m) = (a.len, b.len)\n if n == 0 or m == 0: return\n if min(n, m) <= 60: return convolution_naive(a, b)\n return convolution_fft(a, b
    )\n\n #[ import atcoder/modint ]#\n when not declared ATCODER_MODINT_HPP:\n const ATCODER_MODINT_HPP* = 1\n import std/macros\n #[
    import atcoder/generate_definitions ]#\n when not declared ATCODER_GENERATE_DEFINITIONS_NIM:\n const ATCODER_GENERATE_DEFINITIONS_NIM* =
    1\n import std/macros\n \n type hasInv* = concept x\n x.inv()\n \n template generateDefinitions*(name, l, r, typeObj,
    typeBase, body: untyped): untyped {.dirty.} =\n proc name*(l, r: typeObj): auto {.inline.} =\n type T = l.type\n body\n
     proc name*(l: typeBase; r: typeObj): auto {.inline.} =\n type T = r.type\n body\n proc name*(l: typeObj; r:
    typeBase): auto {.inline.} =\n type T = l.type\n body\n \n template generatePow*(name) {.dirty.} =\n proc pow*(m:
    name; p: SomeInteger): name {.inline.} =\n when name is hasInv:\n if p < 0: return pow(m.inv(), -p)\n else:\n
     doAssert p >= 0\n if (p.type)(0) <= p:\n var\n p = p.uint\n m = m\n result = m.unit
    ()\n while p > 0'u:\n if (p and 1'u) != 0'u: result *= m\n m *= m\n p = p shr 1'u\n proc
    `^`*[T:name](m: T; p: SomeInteger): T {.inline.} = m.pow(p)\n \n macro generateConverter*(name, from_type, to_type) =\n let fname =
    ident(\"to\" & $`name` & \"OfGenerateConverter\")\n quote do:\n type `name`* = `to_type`\n converter `fname`*(a
    :`from_type`):`name` {.used.} =\n `name`.init(a)\n \n type\n StaticModInt*[M: static[int]] = object\n a:uint32\n
    DynamicModInt*[T: static[int]] = object\n a:uint32\n \n type ModInt* = StaticModInt or DynamicModInt\n # type ModInt* = concept x,
    type T\n # T is StaticModInt or T is DynamicModInt\n \n proc isStaticModInt*(T:typedesc[ModInt]):bool = T is StaticModInt\n proc
    isDynamicModInt*(T:typedesc[ModInt]):bool = T is DynamicModInt\n #proc isModInt*(T:typedesc):bool = T.isStaticModInt or T.isDynamicModInt\n
    proc isStatic*(T:typedesc[ModInt]):bool = T is StaticModInt\n proc getMod*[M:static[int]](t:typedesc[StaticModInt[M]]):int {.inline.} = M\n \n
     \n #[ import atcoder/internal_math ]#\n \n proc getBarrett*[T:static[int]](t:typedesc[DynamicModInt[T]]):ptr Barrett =\n var
    Barrett_of_DynamicModInt {.global.} = initBarrett(998244353.uint)\n return Barrett_of_DynamicModInt.addr\n \n proc getMod*[T
    :static[int]](t:typedesc[DynamicModInt[T]]):uint32 {.inline.} =\n (t.getBarrett)[].m.uint32\n proc setMod*[T:static[int]](t
    :typedesc[DynamicModInt[T]], M:SomeInteger){.inline.} =\n (t.getBarrett)[] = initBarrett(M.uint)\n \n proc val*(m: ModInt): int {.inline
    .} = int(m.a)\n \n proc `$`*(m: StaticModInt or DynamicModInt): string {.inline.} = $(m.val())\n \n template umod*[T:ModInt](self:
    typedesc[T] or T):uint32 =\n when T is typedesc:\n when T is StaticModInt:\n T.M.uint32\n elif T is DynamicModInt:\n
     T.getMod()\n else:\n static: assert false\n else: T.umod\n \n template `mod`*[T:ModInt](self:typedesc[T] or T
    ):int = T.umod.int\n \n proc init*[T:ModInt](t:typedesc[T], v: SomeInteger or T): auto {.inline.} =\n when v is T: return v\n else
    :\n when v is SomeUnsignedInt:\n if v.uint < T.umod:\n return T(a:v.uint32)\n else:\n return T(a:(v
    .uint mod T.umod.uint).uint32)\n else:\n var v = v.int\n if 0 <= v:\n if v < T.mod: return T(a:v.uint32)\n
     else: return T(a:(v mod T.mod).uint32)\n else:\n v = v mod T.mod\n if v < 0: v += T.mod\n return
    T(a:v.uint32)\n proc unit*[T:ModInt](t:typedesc[T] or T):T = T.init(1)\n \n template initModInt*(v: SomeInteger or ModInt; M: static[int] =
    1_000_000_007): auto =\n StaticModInt[M].init(v)\n \n # TODO\n # converter toModInt[M:static[int]](n:SomeInteger):StaticModInt[M] {
    .inline.} = initModInt(n, M)\n \n # proc initModIntRaw*(v: SomeInteger; M: static[int] = 1_000_000_007): auto {.inline.} =\n # ModInt[M](v
    .uint32)\n proc raw*[T:ModInt](t:typedesc[T], v:SomeInteger):auto = T(a:v)\n \n proc inv*[T:ModInt](v:T):T {.inline.} =\n var\n
     a = v.a.int\n b = T.mod\n u = 1\n v = 0\n while b > 0:\n let t = a div b\n a -= t * b;swap(a, b)\n
     u -= t * v;swap(u, v)\n return T.init(u)\n \n \n proc `-`*[T:ModInt](m: T): T {.inline.} =\n if int(m.a) == 0: return m\n
    else: return T(a:m.umod() - m.a)\n \n proc `+=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} =\n m.a += T.init(n
    ).a\n if m.a >= T.umod: m.a -= T.umod\n return m\n \n proc `-=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.}
    =\n m.a -= T.init(n).a\n if m.a >= T.umod: m.a += T.umod\n return m\n \n proc `*=`*[T:ModInt](m: var T; n: SomeInteger | T):T {
    .inline discardable.} =\n when T is StaticModInt:\n m.a = (m.a.uint * T.init(n).a.uint mod T.umod).uint32\n elif T is
    DynamicModInt:\n m.a = T.getBarrett[].mul(m.a.uint, T.init(n).a.uint).uint32\n else:\n static: assert false\n return m\n
    \n proc `/=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} =\n m.a = (m.a.uint * T.init(n).inv().a.uint mod T.umod
    ).uint32\n return m\n \n generateDefinitions(`+`, m, n, ModInt, SomeInteger):\n result = T.init(m)\n result += n\n \n
    generateDefinitions(`-`, m, n, ModInt, SomeInteger):\n result = T.init(m)\n result -= n\n \n generateDefinitions(`*`, m, n, ModInt,
    SomeInteger):\n result = T.init(m)\n result *= n\n \n generateDefinitions(`/`, m, n, ModInt, SomeInteger):\n result = T.init(m
    )\n result /= n\n \n generateDefinitions(`==`, m, n, ModInt, SomeInteger):\n result = (T.init(m).val() == T.init(n).val())\n \n
    proc inc*(m: var ModInt):ModInt {.inline discardable.} =\n m.a.inc\n if m.a == m.umod.uint32:\n m.a = 0\n return m\n proc
    `++`*(m: var ModInt):ModInt {.inline discardable.} = m.inc\n \n proc dec*(m: var ModInt):ModInt {.inline discardable.} =\n if m.a == 0
    .uint32:\n m.a = m.umod - 1\n else:\n m.a.dec\n return m\n proc `--`*(m: var ModInt):ModInt {.inline discardable.} = m
    .dec\n \n generatePow(ModInt)\n \n # TODO: intSomeIntegerSystem
    .nimuintconverter\n template useStaticModint*(name, M) =\n generateConverter(name, int, StaticModInt[M])\n
    template useDynamicModInt*(name, M) =\n generateConverter(name, int, DynamicModInt[M])\n \n # TODO:
    Nimstatic[int]使converterconverter使\n #
    modint使useStaticModIntuseDynamicModInt\n useStaticModInt(modint998244353, 998244353)\n
    useStaticModInt(modint1000000007, 1000000007)\n useDynamicModInt(modint, -1)\n \n import std/math as math_lib_modint\n proc
    estimateRational*(a:ModInt, ub:int = int(sqrt(float(ModInt.mod))), output_stderr:static[bool] = false):string =\n var v:seq[tuple[s, n, d:
    int]]\n for d in 1 .. ub:\n var n = (a * d).val\n # n or mod - n\n if n * 2 > a.mod:\n n = - (a.mod - n)\n
     if gcd(n, d) > 1: continue\n v.add((n.abs + d, n, d))\n v.sort\n when output_stderr:\n stderr.write \"estimation result
    : \", v\n return $v[0].n & \"/\" & $v[0].d\n \n # TODO:\n # Modint -> intconvertermint(2) * 3int\n
    # converter toInt*(m: ModInt):int {.inline.} = m.val\n \n \n proc convolution*[T:SomeInteger](a, b:seq[T], M:static[uint] = 998244353):seq[T]
    =\n let (n, m) = (a.len, b.len)\n if n == 0 or m == 0: return newSeq[T]()\n \n type mint = StaticModInt[M.int]\n static:\n
    assert mint is FiniteFieldElem\n return convolution(\n a.map((x:T) => mint.init(x)), \n b.map((x:T) => mint.init(x))\n ).map((x
    :mint) => T(x.val()))\n\n proc convolution_ll*(a, b:seq[int]):seq[int] =\n let (n, m) = (a.len, b.len)\n if n == 0 or m == 0: return
    newSeq[int]()\n const\n MOD1:uint = 754974721 # 2^24\n MOD2:uint = 167772161 # 2^25\n MOD3:uint = 469762049 # 2^26\n
    M2M3 = MOD2 * MOD3\n M1M3 = MOD1 * MOD3\n M1M2 = MOD1 * MOD2\n M1M2M3 = MOD1 * MOD2 * MOD3\n\n i1 = inv_gcd((MOD2 * MOD3).int,
    MOD1.int)[1].uint\n i2 = inv_gcd((MOD1 * MOD3).int, MOD2.int)[1].uint\n i3 = inv_gcd((MOD1 * MOD2).int, MOD3.int)[1].uint\n \n
    let\n c1 = convolution(a, b, MOD1)\n c2 = convolution(a, b, MOD2)\n c3 = convolution(a, b, MOD3)\n \n var c = newSeq[int](n + m
    - 1)\n for i in 0..<n + m - 1:\n var x = 0.uint\n x += (c1[i].uint * i1) mod MOD1 * M2M3\n x += (c2[i].uint * i2) mod MOD2 *
    M1M3\n x += (c3[i].uint * i3) mod MOD3 * M1M2\n # B = 2^63, -B <= x, r(real value) < B\n # (x, x - M, x - 2M, or x - 3M) = r (mod
    2B)\n # r = c1[i] (mod MOD1)\n # focus on MOD1\n # r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)\n # r = x,\n
    # x - M' + (0 or 2B),\n # x - 2M' + (0, 2B or 4B),\n # x - 3M' + (0, 2B, 4B or 6B) (without mod!)\n # (r - x) = 0, (0)\n
     # - M' + (0 or 2B), (1)\n # -2M' + (0 or 2B or 4B), (2)\n # -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)\n # we
    checked that\n # ((1) mod MOD1) mod 5 = 2\n # ((2) mod MOD1) mod 5 = 3\n # ((3) mod MOD1) mod 5 = 4\n# var diff = c1[i]
    - floorMod(x.int, MOD1.int)\n var diff = c1[i] - floorMod(cast[int](x), MOD1.int)\n if diff < 0: diff += MOD1.int\n const offset =
    [0'u, 0'u, M1M2M3, 2'u * M1M2M3, 3'u * M1M2M3]\n x -= offset[diff mod 5]\n c[i] = cast[int](x)\n return c\n"<hide>
var n, m = input(int)
var a = input(int, n).mapIt(it // 100).sorted
var b = input(int, m).mapIt(100 - it).sorted
while b.len < n: b.add(100)
var ans = convolution_ll(a, b)
print(ans[0..<n].join("\n"))
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0