val MOD = 1000000007 fun main(args: Array) { val MAXK = 50050 class ModInt(val v: Int) { val n = (v % MOD + MOD) % MOD constructor(v: Long): this((v % MOD).toInt()) override fun toString() = n.toString() operator fun plus(other: ModInt) = ModInt(this.n + other.n) operator fun plus(other: Int) = this + ModInt(other) operator fun minus(other: ModInt) = ModInt(this.n - other.n) operator fun minus(other: Int) = this - ModInt(other) operator fun times(other: ModInt) = ModInt(((this.n.toLong() * other.n.toLong()) % MOD).toInt()) operator fun times(other: Int) = this * ModInt(other) operator fun unaryMinus() = ModInt(-this.n) fun pow(k: Int): ModInt = when { k == 0 -> ModInt(1) k == 1 -> this k % 2 == 0 -> run { val h = pow(k / 2) h * h } else -> pow(k - 1) * this } } operator fun Int.plus(other: ModInt) = ModInt(this + other.n) operator fun Int.minus(other: ModInt) = ModInt(this - other.n) operator fun Int.times(other: ModInt) = ModInt(((this.toLong() * other.n.toLong()) % MOD).toInt()) fun Int.toModInt() = ModInt(this) val fac = run { var i = 1 generateSequence(1.toModInt(), { it * i++ }).take(MAXK+1).toList() } val inv = run { val ret = Array(MAXK+1) { 0.toModInt() } ret[1] = 1.toModInt() for(i in 2 .. MAXK) { ret[i] = ret[MOD % i] * (MOD - MOD / i) } ret.toList() } fun ModInt.inv() = if(this.n in 1 until inv.size) inv[this.n] else throw ArithmeticException("impossible to divide such huge numbers") operator fun ModInt.div(other: ModInt) = this * other.inv() operator fun ModInt.div(other: Int) = this / ModInt(other) val invfac = run { var i = 1 generateSequence(1.toModInt(), { it * inv[i++] }).take(MAXK+1).toList() } fun comb(n: Int, r: Int): ModInt = fac[n] * invfac[n-r] * invfac[r] operator fun List.plus(other: List) = Array(Math.max(this.size, other.size)) { this.elementAtOrElse(it) { 0.toModInt() } + other.elementAtOrElse(it) { 0.toModInt() } }.toList() operator fun List.minus(other: List) = Array(Math.max(this.size, other.size)) { this.elementAtOrElse(it) { 0.toModInt() } - other.elementAtOrElse(it) { 0.toModInt() } }.toList() data class Complex(val real: Double, val imag: Double) { constructor(real: Int, imag: Double): this(real.toDouble(), imag) constructor(real: Double, imag: Int): this(real, imag.toDouble()) constructor(real: Int, imag: Int): this(real.toDouble(), imag.toDouble()) fun conj() = Complex(real, -imag) operator fun plus (other: Complex) = Complex(real + other.real, imag + other.imag) operator fun minus(other: Complex) = Complex(real - other.real, imag - other.imag) operator fun times(other: Complex) = Complex(real * other.real - imag * other.imag, real * other.imag + imag * other.real) } val tokens = readLine()!!.split(" ") val N = tokens[0].toInt() val K = tokens[1].toInt() val T = tokens[2].toLong() val A = readLine()!!.split(" ").map{ it.toInt().toModInt() }.toList() /*val naiveAnswer = run { fun f(x: Int, k: Int) = A.map{ (it + x).pow(k) }.reduce{ a, b -> a + b } fun g(t: Long, k: Int) = (0L .. t).map{ f((it % MOD).toInt(), k) }.reduce{ a, b -> a + b } Array(K+1) { g(T, it) }.toList() } println(naiveAnswer.joinToString())*/ infix fun List.naivemul(other: List): List { // TODO: FFT로 바꾸기. // 일단은 그냥 곱셈으로 구현하고, polynomial division idea부터 시작 val ret = Array(this.size + other.size - 1) { 0.toModInt() } this.forEachIndexed{ i, u -> other.forEachIndexed { j, v -> ret[i + j] = ret[i + j] + (u * v) } } return ret.toList() } // from here: http://codeforces.com/contest/438/submission/6863336 val MAXLOGL = 18 val MAXL = 1 shl MAXLOGL val bitrev = generateSequence{ IntArray(MAXL+5) { 0 } }.take(MAXLOGL).toList() val w = generateSequence{ Array(MAXL+5) { Complex(0.0, 0.0) } }.take(MAXLOGL).toList() for(l in 0 until MAXLOGL) { w[l][0] = Complex(1, 0) for(i in 0 until (1 shl l)) { bitrev[l][i] = (bitrev[l][i shr 1] shr 1) or ((i and 1) shl (l - 1)) val b = i and -i if(b == i) { w[l][i] = Complex(Math.cos(2 * Math.PI * i / (1 shl l)), Math.sin(2 * Math.PI * i / (1 shl l))) }else { w[l][i] = w[l][b] * w[l][i xor b] } } } fun Array.fft() { val l = (0 until MAXLOGL).find{ this.size <= 1 shl it }!! val n = 1 shl l for(i in 0 until n) { if(i < bitrev[l][i]) { val tmp = this[i] this[i] = this[bitrev[l][i]] this[bitrev[l][i]] = tmp } } var i = 2 var lyc = n shr 1 while(i <= n) { for(j in 0 until n step i) { var x = j var y = j + (i shr 1) var p = 0 for(k in 0 until (i shr 1)) { val tmp = this[y] * w[l][p] this[y] = this[x] - tmp this[x] = this[x] + tmp x += 1 y += 1 p += lyc } } i = i shl 1 lyc = lyc shr 1 } } operator fun List.times(other: List): List { if(this.size + other.size <= 200) return this naivemul other val n = 1 shl (0 until MAXLOGL).find{ (this.size + other.size - 1) <= 1 shl it }!! val a = Array(n) { if(it < this.size) Complex(this[it].n and 32767, this[it].n shr 15) else Complex(0.0, 0.0) } val b = Array(n) { if(it < other.size) Complex(other[it].n and 32767, other[it].n shr 15) else Complex(0.0, 0.0) } a.fft() b.fft() val dfta = Array(n) { Complex(0.0, 0.0) } val dftb = Array(n) { Complex(0.0, 0.0) } val dftc = Array(n) { Complex(0.0, 0.0) } val dftd = Array(n) { Complex(0.0, 0.0) } for(i in 0 until n) { val j = (n - i) and (n - 1) val da = (a[i] + a[j].conj()) * Complex(0.5, 0.0) val db = (a[i] - a[j].conj()) * Complex(0.0, -0.5) val dc = (b[i] + b[j].conj()) * Complex(0.5, 0.0) val dd = (b[i] - b[j].conj()) * Complex(0.0, -0.5) dfta[j] = da * dc dftb[j] = da * dd dftc[j] = db * dc dftd[j] = db * dd } for(i in 0 until n) { a[i] = dfta[i] + dftb[i] * Complex(0.0, 1.0) b[i] = dftc[i] + dftd[i] * Complex(0.0, 1.0) } a.fft() b.fft() return (0 .. Math.min(n, K)).map { i -> if(i < n) { val da = ((a[i].real / n + 0.5).toLong() % MOD) val db = ((a[i].imag / n + 0.5).toLong() % MOD) val dc = ((b[i].real / n + 0.5).toLong() % MOD) val dd = ((b[i].imag / n + 0.5).toLong() % MOD) ModInt(da + ((db + dc) shl 15) + (dd shl 30)) }else { ModInt(0) } }.toList() } operator fun List.times(other: Int) = this.map { it * other } operator fun Int.times (other: List) = other.map { this * it } fun List.getInversePowerSeries(numDegree: Int): List { var g = listOf(this[0].inv()) while(g.size < numDegree + 1) { g = (g * (listOf(2.toModInt()) - g * this)).slice(0 until Math.min(2 * g.size, numDegree + 1)) } return g.slice(0 .. numDegree) } fun List.getInversePowerSeries() = this.getInversePowerSeries(this.size - 1) val polyB = run { fun go(l: Int, r: Int): Pair, List> { if(r - l == 1) return Pair(listOf(1.toModInt()), listOf(1.toModInt(), -A[l])) val m = (l + r) / 2 val (al, bl) = go(l, m) val (ar, br) = go(m, r) return Pair(al * br + ar * bl, bl * br) } val (P, Q) = go(0, N) (P * Q.getInversePowerSeries(K)).slice(0..K).mapIndexed{ i, v -> v * invfac[i] } } val polyC = run { val modintT = ModInt(T) val P1 = invfac.subList(1, K+2).getInversePowerSeries(K) val P2 = run { var powT = ModInt(1) (0..K).map{ powT *= modintT powT * invfac[it+1] }.toList() } var powT = modintT * modintT (P1 * P2).subList(0, K+1).mapIndexed{ j, v -> when(j) { 0 -> modintT + 1 1 -> modintT * (modintT + 1) * inv[2] else -> run { val nxtpowT = powT * modintT val ret = nxtpowT * inv[j+1] + powT * inv[2] + fac[j] * (v - P1[0] * P2[j] - P1[1] * P2[j-1]) powT = nxtpowT ret } } * invfac[j] }.toList() } println((polyB * polyC).subList(0, K+1).mapIndexed{ k, v -> fac[k] * v }.joinToString(" ")) }