結果
問題 | No.1080 Strange Squared Score Sum |
ユーザー | chaemon |
提出日時 | 2020-10-17 01:43:05 |
言語 | Nim (2.0.2) |
結果 |
AC
|
実行時間 | 662 ms / 5,000 ms |
コード長 | 35,109 bytes |
コンパイル時間 | 4,173 ms |
コンパイル使用メモリ | 102,016 KB |
実行使用メモリ | 24,064 KB |
最終ジャッジ日時 | 2024-07-21 01:39:39 |
合計ジャッジ時間 | 13,069 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 321 ms
12,800 KB |
testcase_03 | AC | 626 ms
21,632 KB |
testcase_04 | AC | 151 ms
8,064 KB |
testcase_05 | AC | 165 ms
8,704 KB |
testcase_06 | AC | 34 ms
5,376 KB |
testcase_07 | AC | 74 ms
5,504 KB |
testcase_08 | AC | 319 ms
13,312 KB |
testcase_09 | AC | 299 ms
12,544 KB |
testcase_10 | AC | 35 ms
5,376 KB |
testcase_11 | AC | 609 ms
21,120 KB |
testcase_12 | AC | 292 ms
12,800 KB |
testcase_13 | AC | 617 ms
23,168 KB |
testcase_14 | AC | 306 ms
12,544 KB |
testcase_15 | AC | 2 ms
5,376 KB |
testcase_16 | AC | 662 ms
24,064 KB |
testcase_17 | AC | 342 ms
12,672 KB |
testcase_18 | AC | 338 ms
12,288 KB |
testcase_19 | AC | 341 ms
12,416 KB |
testcase_20 | AC | 610 ms
20,992 KB |
testcase_21 | AC | 606 ms
20,992 KB |
コンパイルメッセージ
/home/judge/data/code/Main.nim(13, 22) Warning: imported and not used: 'streams_lib' [UnusedImport]
ソースコード
# verify-helper: PROBLEM https://yukicoder.me/problems/no/1080 when not declared ATCODER_HEADER_HPP: const ATCODER_HEADER_HPP* = 1 {.hints:off checks:off assertions:on checks:off optimization:speed.} import std/algorithm as algorithm_lib import std/sequtils as sequils_lib import std/tables as tables_lib import std/macros as macros_lib import std/math as math_lib import std/sets as sets_lib import std/strutils as strutils_lib import std/streams as streams_lib import std/strformat as strformat_lib import std/sugar as sugar_lib proc scanf*(formatstr: cstring){.header: "<stdio.h>", varargs.} proc getchar*(): char {.header: "<stdio.h>", varargs.} proc nextInt*(base:int = 0): int = scanf("%lld",addr result) result -= base proc nextFloat*(): float = scanf("%lf",addr result) proc nextString*(): string = var get = false;result = "" while true: var c = getchar() if int(c) > int(' '): get = true;result.add(c) elif get: break template `max=`*(x,y:typed):void = x = max(x,y) template `min=`*(x,y:typed):void = x = min(x,y) template inf*(T): untyped = when T is SomeFloat: T(Inf) elif T is SomeInteger: ((T(1) shl T(sizeof(T)*8-2)) - (T(1) shl T(sizeof(T)*4-1))) else: assert(false) # modSqrt {{{ when not declared ATCODER_MODSQRT_HPP: const ATCODER_MODSQRT_HPP* = 1 when not declared ATCODER_MODINT_HPP: const ATCODER_MODINT_HPP* = 1 type StaticModInt*[M: static[int]] = distinct uint32 DynamicModInt*[T: static[int]] = distinct uint32 type ModInt* = StaticModInt or DynamicModInt proc isStaticModInt*(T:typedesc):bool = T is StaticModInt proc isDynamicModInt*(T:typedesc):bool = T is DynamicModInt proc isModInt*(T:typedesc):bool = T.isStaticModInt or T.isDynamicModInt proc isStatic*(T:typedesc[ModInt]):bool = T is StaticModInt when not declared ATCODER_INTERNAL_MATH_HPP: const ATCODER_INTERNAL_MATH_HPP* = 1 import std/math # Fast moduler by barrett reduction # Reference: https:#en.wikipedia.org/wiki/Barrett_reduction # NOTE: reconsider after Ice Lake type Barrett* = object m*, im:uint # @param m `1 <= m` proc initBarrett*(m:uint):auto = Barrett(m:m, im:(0'u - 1'u) div m + 1) # @return m proc umod*(self: Barrett):uint = self.m {.emit: """ inline unsigned long long calc_mul(const unsigned long long &a, const unsigned long long &b){ return (unsigned long long)(((unsigned __int128)(a)*b) >> 64); } """.} proc calc_mul*(a,b:culonglong):culonglong {.importcpp: "calc_mul(#,#)", nodecl.} # @param a `0 <= a < m` # @param b `0 <= b < m` # @return `a * b % m` proc mul*(self: Barrett, a:uint, b:uint):uint = # [1] m = 1 # a = b = im = 0, so okay # [2] m >= 2 # im = ceil(2^64 / m) # -> im * m = 2^64 + r (0 <= r < m) # let z = a*b = c*m + d (0 <= c, d < m) # a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im # c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2 # ((ab * im) >> 64) == c or c + 1 let z = a * b # #ifdef _MSC_VER # unsigned long long x; # _umul128(z, im, &x); # #else ##TODO # unsigned long long x = # (unsigned long long)(((unsigned __int128)(z)*im) >> 64); # #endif let x = calc_mul(z.culonglong, self.im.culonglong).uint var v = z - x * self.m if self.m <= v: v += self.m return v # @param n `0 <= n` # @param m `1 <= m` # @return `(x ** n) % m` proc pow_mod_constexpr*(x,n,m:int):int = if m == 1: return 0 var r = 1 y = floorMod(x, m) n = n while n != 0: if (n and 1) != 0: r = (r * y) mod m y = (y * y) mod m n = n shr 1 return r.int # Reference: # M. Forisek and J. Jancina, # Fast Primality Testing for Integers That Fit into a Machine Word # @param n `0 <= n` proc is_prime_constexpr*(n:int):bool = if n <= 1: return false if n == 2 or n == 7 or n == 61: return true if n mod 2 == 0: return false var d = n - 1 while d mod 2 == 0: d = d div 2 for a in [2, 7, 61]: var t = d y = pow_mod_constexpr(a, t, n) while t != n - 1 and y != 1 and y != n - 1: y = y * y mod n t = t shl 1 if y != n - 1 and t mod 2 == 0: return false return true proc is_prime*[n:static[int]]():bool = is_prime_constexpr(n) # # # @param b `1 <= b` # # @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g proc inv_gcd*(a, b:int):(int,int) = var a = floorMod(a, b) if a == 0: return (b, 0) # Contracts: # [1] s - m0 * a = 0 (mod b) # [2] t - m1 * a = 0 (mod b) # [3] s * |m1| + t * |m0| <= b var s = b t = a m0 = 0 m1 = 1 while t != 0: var u = s div t s -= t * u; m0 -= m1 * u; # |m1 * u| <= |m1| * s <= b # [3]: # (s - t * u) * |m1| + t * |m0 - m1 * u| # <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u) # = s * |m1| + t * |m0| <= b var tmp = s s = t;t = tmp; tmp = m0;m0 = m1;m1 = tmp; # by [3]: |m0| <= b/g # by g != b: |m0| < b/g if m0 < 0: m0 += b div s return (s, m0) # Compile time primitive root # @param m must be prime # @return primitive root (and minimum in now) proc primitive_root_constexpr*(m:int):int = if m == 2: return 1 if m == 167772161: return 3 if m == 469762049: return 3 if m == 754974721: return 11 if m == 998244353: return 3 var divs:array[20, int] divs[0] = 2 var cnt = 1 var x = (m - 1) div 2 while x mod 2 == 0: x = x div 2 var i = 3 while i * i <= x: if x mod i == 0: divs[cnt] = i cnt.inc while x mod i == 0: x = x div i i += 2 if x > 1: divs[cnt] = x cnt.inc var g = 2 while true: var ok = true for i in 0..<cnt: if pow_mod_constexpr(g, (m - 1) div divs[i], m) == 1: ok = false break if ok: return g g.inc proc primitive_root*[m:static[int]]():auto = primitive_root_constexpr(m) discard proc getBarrett*[T:static[int]](t:typedesc[DynamicModInt[T]], set = false, M:SomeInteger = 0.uint32):ptr Barrett = var Barrett_of_DynamicModInt {.global.} = initBarrett(998244353.uint) return Barrett_of_DynamicModInt.addr proc getMod*[T:static[int]](t:typedesc[DynamicModInt[T]]):uint32 {.inline.} = (t.getBarrett)[].m.uint32 proc setMod*[T:static[int]](t:typedesc[DynamicModInt[T]], M:SomeInteger){.used inline.} = (t.getBarrett)[] = initBarrett(M.uint) proc `$`*(m: ModInt): string {.inline.} = $m.int template umod*[T:ModInt](self: typedesc[T]):uint32 = when T is StaticModInt: T.M elif T is DynamicModInt: T.getMod() else: static: assert false template umod*[T:ModInt](self: T):uint32 = self.type.umod proc `mod`*[T:ModInt](self:typedesc[T]):int = T.umod.int proc `mod`*[T:ModInt](self:T):int = self.umod.int proc init*[T:ModInt](t:typedesc[T], v: SomeInteger or T): auto {.inline.} = when v is T: return v else: when v is SomeUnsignedInt: if v.uint < T.umod: return T(v.uint32) else: return T((v.uint mod T.umod.uint).uint32) else: var v = v.int if 0 <= v: if v < T.mod: return T(v.uint32) else: return T((v mod T.mod).uint32) else: v = v mod T.mod if v < 0: v += T.mod return T(v.uint32) template initModInt*(v: SomeInteger or ModInt; M: static[int] = 1_000_000_007): auto = StaticModInt[M].init(v) # TODO # converter toModInt[M:static[int]](n:SomeInteger):StaticModInt[M] {.inline.} = initModInt(n, M) # proc initModIntRaw*(v: SomeInteger; M: static[int] = 1_000_000_007): auto {.inline.} = # ModInt[M](v.uint32) proc raw*[T:ModInt](t:typedesc[T], v:SomeInteger):auto = T(v) proc inv*[T:ModInt](v:T):T {.inline.} = var a = v.int b = T.mod u = 1 v = 0 while b > 0: let t = a div b a -= t * b;swap(a, b) u -= t * v;swap(u, v) return T.init(u) proc val*(m: ModInt): int {.inline.} = int(m) proc `-`*[T:ModInt](m: T): T {.inline.} = if int(m) == 0: return m else: return T(m.umod() - uint32(m)) template generateDefinitions(name, l, r, body: untyped): untyped {.dirty.} = proc name*[T:ModInt](l: T; r: T): auto {.inline.} = body proc name*[T:ModInt](l: SomeInteger; r: T): auto {.inline.} = body proc name*[T:ModInt](l: T; r: SomeInteger): auto {.inline.} = body proc `+=`*[T:ModInt](m: var T; n: SomeInteger | T) {.inline.} = uint32(m) += T.init(n).uint32 if uint32(m) >= T.umod: uint32(m) -= T.umod proc `-=`*[T:ModInt](m: var T; n: SomeInteger | T) {.inline.} = uint32(m) -= T.init(n).uint32 if uint32(m) >= T.umod: uint32(m) += T.umod proc `*=`*[T:ModInt](m: var T; n: SomeInteger | T) {.inline.} = when T is StaticModInt: uint32(m) = (uint(m) * T.init(n).uint mod T.umod).uint32 elif T is DynamicModInt: uint32(m) = T.getBarrett[].mul(uint(m), T.init(n).uint).uint32 else: static: assert false proc `/=`*[T:ModInt](m: var T; n: SomeInteger | T) {.inline.} = uint32(m) = (uint(m) * T.init(n).inv().uint mod T.umod).uint32 # proc `==`*[T:ModInt](m: T; n: SomeInteger | T): bool {.inline.} = # int(m) == T.init(n).int generateDefinitions(`+`, m, n): result = T.init(m) result += n generateDefinitions(`-`, m, n): result = T.init(m) result -= n generateDefinitions(`*`, m, n): result = T.init(m) result *= n generateDefinitions(`/`, m, n): result = T.init(m) result /= n generateDefinitions(`==`, m, n): result = (T.init(m).int == T.init(n).int) proc inc*[T:ModInt](m: var T) {.inline.} = uint32(m).inc if m == T.umod: uint32(m) = 0 proc dec*[T:ModInt](m: var T) {.inline.} = if m == 0: uint32(m) = T.umod - 1 else: uint32(m).dec proc pow*[T:ModInt](m: T; p: SomeInteger): T {.inline.} = assert 0 <= p var p = p.int m = m uint32(result) = 1 while p > 0: if (p and 1) == 1: result *= m m *= m p = p shr 1 proc `^`*[T:ModInt](m: T; p: SomeInteger): T {.inline.} = m.pow(p) type modint998244353* = StaticModInt[998244353] type modint1000000007* = StaticModInt[1000000007] type modint* = DynamicModInt[-1] discard import std/options proc modSqrt*[T:ModInt](a:T):Option[T] = let p = a.umod.int if a == 0: return T(0).some if p == 2: return T(a).some if a.pow((p - 1) shr 1) != 1: return none(T) var b = T(1) while b.pow((p - 1) shr 1) == 1: b += 1 var e = 0 m = p - 1 while m mod 2 == 0: m = m shr 1; e.inc var x = a.pow((m - 1) shr 1) y = a * x * x x *= a var z = b.pow(m) while y != 1: var j = 0 t = y while t != 1: j.inc t *= t z = z.pow(1 shl (e - j - 1)) x *= z z *= z y *= z e = j return T(x).some #}}} when not declared ATCODER_NTT_HPP: const ATCODER_NTT_HPP* = 1 when not declared ATCODER_ELEMENT_CONCEPTS_HPP: const ATCODER_ELEMENT_CONCEPTS_HPP* = 1 proc inv*[T:SomeFloat](a:T):auto = T(1) / a proc init*(self:typedesc[SomeFloat], a:SomeNumber):auto = self(a) type AdditiveGroupElem* = concept x, type T x + x x - x -x T(0) type MultiplicativeGroupElem* = concept x, type T x * x x / x # x.inv() T(1) type RingElem* = concept x, type T x + x x - x -x x * x T(0) T(1) type FieldElem* = concept x, type T x + x x - x x * x x / x -x # x.inv() T(0) T(1) type FiniteFieldElem* = concept x, type T x is FieldElem T.mod() T.mod() is int x.pow(1000000) type hasInf* = concept x, type T T(Inf) discard when not declared ATCODER_PARTICULAR_MOD_CONVOLUTION: const ATCODER_PARTICULAR_MOD_CONVOLUTION* = 1 when not declared ATCODER_CONVOLUTION_HPP: const ATCODER_CONVOLUTION_HPP* = 1 import std/math import std/sequtils import std/sugar when not declared ATCODER_INTERNAL_BITOP_HPP: const ATCODER_INTERNAL_BITOP_HPP* = 1 import std/bitops #ifdef _MSC_VER #include <intrin.h> #endif # @param n `0 <= n` # @return minimum non-negative `x` s.t. `n <= 2**x` proc ceil_pow2*(n:SomeInteger):int = var x = 0 while (1.uint shl x) < n.uint: x.inc return x # @param n `1 <= n` # @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0` proc bsf*(n:SomeInteger):int = return countTrailingZeroBits(n) discard # template <class mint, internal::is_static_modint_t<mint>* = nullptr> proc butterfly*[mint:FiniteFieldElem](a:var seq[mint]) = const g = primitive_root[mint.mod]() let n = a.len h = ceil_pow2(n) var first {.global.} = true sum_e {.global.} :array[30, mint] # sum_e[i] = ies[0] * ... * ies[i - 1] * es[i] if first: first = false var es, ies:array[30, mint] # es[i]^(2^(2+i)) == 1 let cnt2 = bsf(mint.mod - 1) mixin inv var e = mint(g).pow((mint.mod - 1) shr cnt2) ie = e.inv() for i in countdown(cnt2, 2): # e^(2^i) == 1 es[i - 2] = e ies[i - 2] = ie e *= e ie *= ie var now = mint(1) for i in 0..cnt2 - 2: sum_e[i] = es[i] * now now *= ies[i] for ph in 1..h: let w = 1 shl (ph - 1) p = 1 shl (h - ph) var now = mint(1) for s in 0..<w: let offset = s shl (h - ph + 1) for i in 0..<p: let l = a[i + offset] r = a[i + offset + p] * now a[i + offset] = l + r a[i + offset + p] = l - r now *= sum_e[bsf(not s)] proc butterfly_inv*[mint:FiniteFieldElem](a:var seq[mint]) = const g = primitive_root[mint.mod]() let n = a.len h = ceil_pow2(n) var first{.global.} = true sum_ie{.global.}:array[30, mint] # sum_ie[i] = es[0] * ... * es[i - 1] * ies[i] if first: first = false var es, ies: array[30, mint] # es[i]^(2^(2+i)) == 1 let cnt2 = bsf(mint.mod - 1) mixin inv var e = mint(g).pow((mint.mod - 1) shr cnt2) ie = e.inv() for i in countdown(cnt2, 2): # e^(2^i) == 1 es[i - 2] = e ies[i - 2] = ie e *= e ie *= ie var now = mint(1) for i in 0..cnt2 - 2: sum_ie[i] = ies[i] * now now *= es[i] mixin init for ph in countdown(h, 1): let w = 1 shl (ph - 1) p = 1 shl (h - ph) var inow = mint(1) for s in 0..<w: let offset = s shl (h - ph + 1) for i in 0..<p: let l = a[i + offset] r = a[i + offset + p] a[i + offset] = l + r a[i + offset + p] = mint.init((mint.mod + l.val - r.val) * inow.val) inow *= sum_ie[bsf(not s)] # template <class mint, internal::is_static_modint_t<mint>* = nullptr> proc convolution*[mint:FiniteFieldElem](a, b:seq[mint]):seq[mint] = var n = a.len m = b.len mixin inv if n == 0 or m == 0: return newSeq[mint]() var (a, b) = (a, b) if min(n, m) <= 60: if n < m: swap(n, m) swap(a, b) var ans = newSeq[mint](n + m - 1) for i in 0..<n: for j in 0..<m: ans[i + j] += a[i] * b[j] return ans let z = 1 shl ceil_pow2(n + m - 1) a.setlen(z) butterfly(a) b.setlen(z) butterfly(b) for i in 0..<z: a[i] *= b[i] butterfly_inv(a) a.setlen(n + m - 1) let iz = mint(z).inv() for i in 0..<n+m-1: a[i] *= iz return a # template <unsigned int mod = 998244353, # class T, # std::enable_if_t<internal::is_integral<T>::value>* = nullptr> proc convolution*[T:SomeInteger](a, b:seq[T], M:static[uint] = 998244353):seq[T] = let (n, m) = (a.len, b.len) if n == 0 or m == 0: return newSeq[T]() type mint = StaticModInt[M.int] static: assert mint is FiniteFieldElem return convolution( a.map((x:T) => mint.init(x)), b.map((x:T) => mint.init(x)) ).map((x:mint) => T(x.val())) proc convolution_ll*(a, b:seq[int]):seq[int] = let (n, m) = (a.len, b.len) if n == 0 or m == 0: return newSeq[int]() const MOD1:uint = 754974721 # 2^24 MOD2:uint = 167772161 # 2^25 MOD3:uint = 469762049 # 2^26 M2M3 = MOD2 * MOD3 M1M3 = MOD1 * MOD3 M1M2 = MOD1 * MOD2 M1M2M3 = MOD1 * MOD2 * MOD3 i1 = inv_gcd((MOD2 * MOD3).int, MOD1.int)[1].uint i2 = inv_gcd((MOD1 * MOD3).int, MOD2.int)[1].uint i3 = inv_gcd((MOD1 * MOD2).int, MOD3.int)[1].uint let c1 = convolution(a, b, MOD1) c2 = convolution(a, b, MOD2) c3 = convolution(a, b, MOD3) var c = newSeq[int](n + m - 1) for i in 0..<n + m - 1: var x = 0.uint x += (c1[i].uint * i1) mod MOD1 * M2M3 x += (c2[i].uint * i2) mod MOD2 * M1M3 x += (c3[i].uint * i3) mod MOD3 * M1M2 # B = 2^63, -B <= x, r(real value) < B # (x, x - M, x - 2M, or x - 3M) = r (mod 2B) # r = c1[i] (mod MOD1) # focus on MOD1 # r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B) # r = x, # x - M' + (0 or 2B), # x - 2M' + (0, 2B or 4B), # x - 3M' + (0, 2B, 4B or 6B) (without mod!) # (r - x) = 0, (0) # - M' + (0 or 2B), (1) # -2M' + (0 or 2B or 4B), (2) # -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1) # we checked that # ((1) mod MOD1) mod 5 = 2 # ((2) mod MOD1) mod 5 = 3 # ((3) mod MOD1) mod 5 = 4 var diff = c1[i] - floorMod(x.int, MOD1.int) if diff < 0: diff += MOD1.int const offset = [0'u, 0'u, M1M2M3, 2'u * M1M2M3, 3'u * M1M2M3] x -= offset[diff mod 5] c[i] = x.int return c discard import std/sequtils type ParticularModConvolution* = object discard type ParticularModFFTType[T:StaticModInt] = seq[T] proc fft*[T:StaticModInt](t:typedesc[ParticularModConvolution], a:seq[T]):ParticularModFFTType[T] {.inline.} = result = a butterfly(result) proc inplace_partial_dot*[T](t:typedesc[ParticularModConvolution], a:var ParticularModFFTType[T], b:ParticularModFFTType[T], p:Slice[int]) = for i in p: a[i] *= b[i] proc dot*[T](t:typedesc[ParticularModConvolution], a, b:ParticularModFFTType[T]):ParticularModFFTType[T] = result = a inplace_partial_dot(t, result, b, 0..<a.len) proc ifft*[T](t:typedesc[ParticularModConvolution], a:ParticularModFFTType[T]):seq[T] {.inline.} = result = a result.butterfly_inv let iz = T(a.len).inv() result.applyIt(it * iz) proc convolution*[T:StaticModInt](t:typedesc[ParticularModConvolution], a, b:seq[T]):auto {.inline.} = convolution(a, b) discard when not declared ATCODER_ARBITRARY_MOD_CONVOLUTION: const ATCODER_ARBITRARY_MOD_CONVOLUTION* = 1 import std/sequtils type ArbitraryModConvolution* = object discard const m0 = 167772161.uint m1 = 469762049.uint m2 = 754974721.uint type mint0 = StaticModInt[m0.int] mint1 = StaticModInt[m1.int] mint2 = StaticModint[m2.int] type ArbitraryModFFTElem* = (mint0, mint1, mint2) proc setLen*(v:var (seq[mint0], seq[mint1], seq[mint2]), n:int) = v[0].setLen(n) v[1].setLen(n) v[2].setLen(n) proc `*=`(a:var ArbitraryModFFTElem, b:ArbitraryModFFTElem) = a[0] *= b[0];a[1] *= b[1];a[2] *= b[2] proc `-`(a:ArbitraryModFFTElem):auto = (-a[0], -a[1], -a[2]) const r01 = mint1.init(m0).inv().uint r02 = mint2.init(m0).inv().uint r12 = mint2.init(m1).inv().uint r02r12 = r02 * r12 mod m2 proc fft*[T:ModInt](t:typedesc[ArbitraryModConvolution], a:seq[T]):auto {.inline.} = type F = ParticularModConvolution var v0 = newSeq[mint0](a.len) v1 = newSeq[mint1](a.len) v2 = newSeq[mint2](a.len) for i in 0..<a.len: v0[i] = mint0.init(a[i].int) v1[i] = mint1.init(a[i].int) v2[i] = mint2.init(a[i].int) v0 = F.fft(v0) v1 = F.fft(v1) v2 = F.fft(v2) return (v0,v1,v2) proc inplace_partial_dot*(t:typedesc[ArbitraryModConvolution], a:var (seq[mint0], seq[mint1], seq[mint2]), b:(seq[mint0], seq[mint1], seq[mint2]), p:Slice[int]):auto = for i in p: a[0][i] *= b[0][i] a[1][i] *= b[1][i] a[2][i] *= b[2][i] proc dot*(t:typedesc[ArbitraryModConvolution], a, b:(seq[mint0], seq[mint1], seq[mint2])):auto = result = a t.inplace_partial_dot(result, b, 0..<a[0].len) proc calc_garner[T:ModInt](a0:seq[mint0], a1:seq[mint1], a2:seq[mint2], deg:int):seq[T] = let w1 = m0 mod T.umod w2 = w1 * m1 mod T.umod result = newSeq[T](deg) for i in 0..<deg: let (n0, n1, n2) = (a0[i].uint, a1[i].uint, a2[i].uint) b = (n1 + m1 - n0) * r01 mod m1 c = ((n2 + m2 - n0) * r02r12 + (m2 - b) * r12) mod m2 result[i] = T.init(n0 + b * w1 + c * w2) proc ifft*[T:ModInt](t:typedesc[ArbitraryModConvolution], a:(seq[mint0], seq[mint1], seq[mint2]), deg = -1):auto {.inline.} = type F = ParticularModConvolution let deg = if deg == -1: a[0].len else: deg a0 = F.ifft(a[0]) a1 = F.ifft(a[1]) a2 = F.ifft(a[2]) return calc_garner[T](a0, a1, a2, deg) proc convolution*[T:ModInt](t:typedesc[ArbitraryModConvolution], a, b:seq[T]):seq[T] {.inline.} = proc f0(x:T):mint0 = mint0.init(x.int) proc f1(x:T):mint1 = mint1.init(x.int) proc f2(x:T):mint2 = mint2.init(x.int) let c0 = convolution(a.map(f0), b.map(f0)) c1 = convolution(a.map(f1), b.map(f1)) c2 = convolution(a.map(f2), b.map(f2)) return calc_garner[T](c0, c1, c2, a.len + b.len - 1) discard import std/bitops template get_fft_type*[T:FiniteFieldElem](self: typedesc[T]):typedesc = when T.isStatic and countTrailingZeroBits(T.mod - 1) >= 20: ParticularModConvolution else: ArbitraryModConvolution proc fft*[T:FiniteFieldElem](a:seq[T]):auto = fft(get_fft_type(T), a) proc ifft*(a:auto, T:typedesc[FiniteFieldElem]):auto = ifft[T](get_fft_type(T), a) proc dot*(a, b:auto, T:typedesc[FiniteFieldElem]):auto = dot(get_fft_type(T), a, b) proc inplace_partial_dot*(a:var auto, b:auto, p:Slice[int], T:typedesc[FiniteFieldElem]) = inplace_partial_dot(get_fft_type(T), a, b, p) proc multiply*[T:FiniteFieldElem](a, b:seq[T]):seq[T] = convolution(get_fft_type(T), a, b) # FormalPowerSeries {{{ when not declared ATCODER_FORMAL_POWER_SERIES: const ATCODER_FORMAL_POWER_SERIES* = 1 import std/sequtils import std/strformat import std/options import std/macros import std/tables import std/algorithm type FormalPowerSeries*[T:FieldElem] = seq[T] template initFormalPowerSeries*[T:FieldElem](n:int):FormalPowerSeries[T] = FormalPowerSeries[T](newSeq[T](n)) template initFormalPowerSeries*[T:FieldElem](data:seq or array):FormalPowerSeries[T] = when data is FormalPowerSeries[T]: data else: var result = newSeq[T](data.len) for i, it in data: result[i] = T.init(it) result template init*[T:FieldElem](self:typedesc[FormalPowerSeries[T]], data:typed):auto = initFormalPowerSeries[T](data) macro revise(a, b) = parseStmt(fmt"""let {a.repr} = if {a.repr} == -1: {b.repr} else: {a.repr}""") proc shrink*[T](self: var FormalPowerSeries[T]) = while self.len > 0 and self[^1] == 0: discard self.pop() # operators +=, -=, *=, mod=, -, /= {{{ proc `+=`*(self: var FormalPowerSeries, r:FormalPowerSeries) = if r.len > self.len: self.setlen(r.len) for i in 0..<r.len: self[i] += r[i] proc `+=`*[T](self: var FormalPowerSeries[T], r:T) = if self.len == 0: self.setlen(1) self[0] += r proc `-=`*[T](self: var FormalPowerSeries[T], r:FormalPowerSeries[T]) = if r.len > self.len: self.setlen(r.len) for i in 0..<r.len: self[i] -= r[i] # self.shrink() proc `-=`*[T](self: var FormalPowerSeries[T], r:T) = if self.len == 0: self.setlen(1) self[0] -= r # self.shrink() proc `*=`*[T](self: var FormalPowerSeries[T], v:T) = self.applyIt(it * v) proc multRaw*[T](a, b:FormalPowerSeries[T]):FormalPowerSeries[T] = result = initFormalPowerSeries[T](a.len + b.len - 1) for i in 0..<a.len: for j in 0..<b.len: result[i + j] += a[i] * b[j] proc `*=`*[T](self: var FormalPowerSeries[T], r: FormalPowerSeries[T]) = if self.len == 0 or r.len == 0: self.setlen(0) else: mixin multiply self = multiply(self, r) proc `mod=`*[T](self: var FormalPowerSeries[T], r:FormalPowerSeries[T]) = self -= (self div r) * r self.setLen(r.len - 1) proc `-`*[T](self: FormalPowerSeries[T]):FormalPowerSeries[T] = var ret = self ret.applyIt(-it) return ret proc `/=`*[T](self: var FormalPowerSeries[T], v:T) = self.applyIt(it / v) #}}} proc rev*[T](self: FormalPowerSeries[T], deg = -1):auto = result = self if deg != -1: result.setlen(deg) result.reverse proc pre*[T](self: FormalPowerSeries[T], sz:int):auto = result = self result.setlen(min(self.len, sz)) proc `shr`*[T](self: FormalPowerSeries[T], sz:int):auto = if self.len <= sz: return initFormalPowerSeries[T](0) result = self if sz >= 1: result.delete(0, sz - 1) proc `shl`*[T](self: FormalPowerSeries[T], sz:int):auto = result = initFormalPowerSeries[T](sz) result = result & self proc diff*[T](self: FormalPowerSeries[T]):auto = let n = self.len result = initFormalPowerSeries[T](max(0, n - 1)) for i in 1..<n: result[i - 1] = self[i] * T(i) proc integral*[T](self: FormalPowerSeries[T]):auto = let n = self.len result = initFormalPowerSeries[T](n + 1) result[0] = T(0) for i in 0..<n: result[i + 1] = self[i] / T(i + 1) proc EQUAL*[T](a, b:T):bool = when T is hasInf: return (abs(a - b) < T(0.0000001)) else: return a == b # F(0) must not be 0 proc inv*[T](self: FormalPowerSeries[T], deg = -1):auto = assert(not EQUAL(self[0], T(0))) deg.revise(self.len) # type F = T.get_fft_type() # when T is ModInt: when true: proc invFast[T](self: FormalPowerSeries[T]):auto = # assert(self[0] != T(0)) let n = self.len var res = initFormalPowerSeries[T](1) res[0] = T(1) / self[0] var d = 1 while d < n: var f, g = initFormalPowerSeries[T](2 * d) for j in 0..<min(n, 2 * d): f[j] = self[j] for j in 0..<d: g[j] = res[j] let g1 = fft(g) f = ifft(dot(fft(f), g1, T), T) for j in 0..<d: f[j] = T(0) f[j + d] = -f[j + d] f = ifft(dot(fft(f), g1, T), T) f[0..<d] = res[0..<d] res = f d = d shl 1 return res.pre(n) var ret = self ret.setlen(deg) return ret.invFast() # else: # var ret = initFormalPowerSeries[T](1) # ret[0] = T(1) / self[0] # var i = 1 # while i < deg: # ret = (ret + ret - ret * ret * self.pre(i shl 1)).pre(i shl 1) # i = i shl 1 # return ret.pre(deg) proc `/=`*[T](self: var FormalPowerSeries[T], r: FormalPowerSeries[T]) = self *= r.inv() proc `div=`*[T](self: var FormalPowerSeries[T], r: FormalPowerSeries[T]) = if self.len < r.len: self.setlen(0) else: let n = self.len - r.len + 1 self = (self.rev().pre(n) * r.rev().inv(n)).pre(n).rev(n) # operators +, -, *, div, mod {{{ macro declareOp(op) = fmt"""proc `{op}`*[T](self:FormalPowerSeries[T];r:FormalPowerSeries[T] or T):FormalPowerSeries[T] = result = self;result {op}= r proc `{op}`*[T](self: not FormalPowerSeries, r:FormalPowerSeries[T]):FormalPowerSeries[T] = result = initFormalPowerSeries[T](@[T(self)]);result {op}= r""".parseStmt declareOp(`+`) declareOp(`-`) declareOp(`*`) declareOp(`/`) proc `div`*[T](self, r:FormalPowerSeries[T]):FormalPowerSeries[T] = result = self;result.`div=` (r) proc `mod`*[T](self, r:FormalPowerSeries[T]):FormalPowerSeries[T] = result = self;result.`mod=` (r) # }}} # F(0) must be 1 proc log*[T](self:FormalPowerSeries[T], deg = -1):auto = assert EQUAL(self[0], T(1)) deg.revise(self.len) return (self.diff() * self.inv(deg)).pre(deg - 1).integral() proc expFast[T:FieldElem](self: FormalPowerSeries[T], deg:int):auto = deg.revise(self.len) assert EQUAL(self[0], T(0)) var inv = newSeqOfCap[T](deg + 1) inv.add(T(0)) inv.add(T(1)) proc inplace_integral(F:var FormalPowerSeries[T]) = let n = F.len when T is FiniteFieldElem: let M = T.mod while inv.len <= n: let i = inv.len when T is FiniteFieldElem: inv.add((-inv[M mod i]) * (M div i)) else: inv.add(T(1)/T(i)) F = @[T(0)] & F for i in 1..n: F[i] *= inv[i] proc inplace_diff(F:var FormalPowerSeries[T]):auto = if F.len == 0: return F = F[1..<F.len] var coeff = T(1) let one = T(1) for i in 0..<F.len: F[i] *= coeff coeff += one mixin fft, ifft, dot type FFTType = fft(initFormalPowerSeries[T](0)).type mixin inplace_partial_dot, setLen var b = @[T(1), if 1 < self.len: self[1] else: T(0)] c = @[T(1)] z1f:FFTType z2 = @[T(1), T(0)] z2f = z2.fft var m = 2 while m < deg: var y = b y.setLen(2 * m) var yf = y.fft z1f = z2f var zf = yf zf.setLen(m) inplace_partial_dot(zf, z1f, 0..<m, T) var z = zf.ifft(T) for i in 0..<m div 2: z[i] = T(0) zf = z.fft z = ifft(dot(zf, z1f, T), T) for i in 0..<m:z[i] *= -1 c = c & z[m div 2..^1] z2 = c z2.setLen(2 * m) z2f = z2.fft var x = self[0..<min(self.len, m)] inplace_diff(x) x.add(T(0)) var xf = x.fft inplace_partial_dot(xf, yf, 0..<m, T) x = xf.ifft(T) x -= b.diff() x.setLen(2 * m) for i in 0..<m - 1: x[m + i] = x[i]; x[i] = T(0) xf = x.fft inplace_partial_dot(xf, z2f, 0..<2*m, T) x = xf.ifft(T) discard x.pop() inplace_integral(x) for i in m..<min(self.len, 2 * m): x[i] += self[i] for i in 0..<m: x[i] = T(0) xf = x.fft inplace_partial_dot(xf, yf, 0..<2*m, T) x = xf.ifft(T) b = b & x[m..^1] m *= 2 return b[0..<deg] # F(0) must be 0 proc exp*[T](self: FormalPowerSeries[T], deg = -1):auto = assert EQUAL(self[0], T(0)) deg.revise(self.len) when true: var self = self self.setLen(deg) return self.exp_fast(deg) else: ret = initFormalPowerSeries[T](@[T(1)]) var i = 1 while i < deg: ret = (ret * (pre(i shl 1) + T(1) - ret.log(i shl 1))).pre(i shl 1) i = i shl 1 return ret.pre(deg) proc pow*[T:FieldElem](self: FormalPowerSeries[T], k:int, deg = -1):FormalPowerSeries[T] = mixin pow, init var self = self let n = self.len deg.revise(n) self.setLen(deg) for i in 0..<n: if not EQUAL(self[i], T(0)): let rev = T(1) / self[i] result = (((self * rev) shr i).log(deg) * T.init(k)).exp() * (self[i].pow(k)) if i * k > deg: return initFormalPowerSeries[T](deg) result = (result shl (i * k)).pre(deg) if result.len < deg: result.setlen(deg) return return self proc eval*[T](self: FormalPowerSeries[T], x:T):T = var (r, w) = (T(0), T(1)) for v in self: r += w * v w *= x return r proc powMod*[T](self: FormalPowerSeries[T], n:int, M:FormalPowerSeries[T]):auto = assert M[^1] != T(0) let modinv = M.rev().inv() proc getDiv(base:FormalPowerSeries[T]):FormalPowerSeries[T] = var base = base if base.len < M.len: base.setlen(0) return base let n = base.len - M.len + 1 return (base.rev().pre(n) * modinv.pre(n)).pre(n).rev(n) var n = n x = self result = initFormalPowerSeries[T](M.len - 1) result[0] = T(1) while n > 0: if (n and 1) > 0: result *= x result -= getDiv(result) * M result = result.pre(M.len - 1) x *= x x -= getDiv(x) * M x = x.pre(M.len - 1) n = n shr 1 # }}} import std/options type mint = StaticModInt[1000000009] let N = nextInt() let im = modSqrt(mint.init(-1)).get() var f = mint(1) P = initFormalPowerSeries[mint](N + 1) for i in 1..N: f *= mint(i) P[i] = mint(i + 1).pow(2) let e1 = exp(P * im) e2 = exp(P * (-im)) sinP = (e1 - e2) / (im * 2) cosP = (e1 + e2) / mint(2) ans = (sinP + cosP) * f for i,a in ans: if i > 0: echo a