Problem:
Score : 500 points

Problem Statement

There are N blocks arranged in a row. Let us paint these blocks.

We will consider two ways to paint the blocks different if and only if there is a block painted in different colors in those two ways.

Find the number of ways to paint the blocks under the following conditions:

For each block, use one of the M colors, Color 1 through Color M, to paint it. It is not mandatory to use all the colors.

There may be at most K pairs of adjacent blocks that are painted in the same color.

Since the count may be enormous, print it modulo 998244353.

Constraints

All values in input are integers.

1 \leq N, M \leq 2 \times 10^5

0 \leq K \leq N - 1

Input

Input is given from Standard Input in the following format:

N M K

Output

Print the answer.

Sample Input 1

3 2 1

Sample Output 1

6

The following ways to paint the blocks satisfy the conditions: 112, 121, 122, 211, 212, and 221. Here, digits represent the colors of the blocks.

Sample Input 2

100 100 0

Sample Output 2

73074801

Sample Input 3

60522 114575 7559

Sample Output 3

479519525

Solution in Kotlin (1.3.71) (judge verdict: Accepted)

import java.io.PrintWriter

fun main() = abc167e()

@OptIn(ExperimentalStdlibApi::class)
fun abc167e() = IO_abc167e().exec {
    val (n, m, k) = readIntList(3)

    val biCoef = BiCoef(n)
    var answer = Mint()

    for (x in 0..k) {
        answer += m.toMint() * modPow(m - 1L, n - x - 1L) * biCoef.nCr(n - 1, x)
    }

    println(answer)
}

private const val MOD = 998244353L

private fun modPow(n: Long, p: Long): Long {
    var x = n
    var y = p
    var result = 1L
    x %= MOD
    while (y > 0) {
        if (y % 2 == 1L)
            result = (result * x) % MOD
        y = y shr 1
        x = (x * x) % MOD
    }
    return result
}


@Suppress("unused")
private class BiCoef(max: Int) {
    private val fact = LongArray(max + 1)
    private val fInv = LongArray(max + 1)
    private val inv = LongArray(max + 1)

    init {
        fact[0] = 1
        fact[1] = 1
        fInv[0] = 1
        fInv[1] = 1
        inv[1] = 1
        for (i in 2..max) {
            fact[i] = fact[i - 1] * i % MOD
            inv[i] = MOD - inv[(MOD % i).toInt()] * (MOD / i) % MOD
            fInv[i] = fInv[i - 1] * inv[i] % MOD
        }
    }

    fun fact(n: Int): Long = if (n < 0) 0 else fact[n]
    fun inv(n: Int): Long = if (n < 0) 0 else inv[n]
    fun fInv(n: Int): Long = if (n < 0) 0 else fInv[n]
    fun comb(n: Int, k: Int): Long = nCr(n, k)
    fun nCr(n: Int, k: Int): Long = if (n < k || n < 0 || k < 0) 0 else fact[n] * (fInv[k] * fInv[n - k] % MOD) % MOD
    fun perm(n: Int, k: Int): Long = nPr(n, k)
    fun nPr(n: Int, k: Int): Long = if (n < k || n < 0 || k < 0) 0 else fact[n] * fInv[n - k] % MOD % MOD
}

private fun Long.toMint() = Mint(this)
private fun Int.toMint() = Mint(this.toLong())

private class Mint(value: Long = 0L) {
    constructor(other: Mint) : this(other.value)

    private val value = if (value < 0) (value % MOD) + MOD else value % MOD
    operator fun unaryPlus() = this
    operator fun unaryMinus() = Mint(MOD - this.value)
    operator fun inc() = this.plus(1)
    operator fun dec() = this.minus(1)
    operator fun plus(other: Long) = Mint(this.value + other)
    operator fun plus(other: Mint) = this.plus(other.value)
    operator fun minus(other: Long) = Mint(this.value - other)
    operator fun minus(other: Mint) = this.plus(-other)
    operator fun times(other: Long) = Mint(this.value * other)
    operator fun times(other: Mint) = this.times(other.value)
    operator fun div(other: Long) = this.times(modPow(other, MOD - 2))
    operator fun div(other: Mint) = this.div(other.value)
    fun mod(mod: Long) = Mint(this.value % mod)
    fun modPow(other: Long) = Mint(modPow(this.value, other))
    override fun toString() = this.value.toString()
    override fun hashCode() = value.hashCode()
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as Mint
        return value == other.value
    }
}

//region
@Suppress("unused", "ClassName", "SpellCheckingInspection", "ConvertToStringTemplate")
private class IO_abc167e {
    private val input = System.`in`
    private val buffer = ByteArray(1024)
    private var pointer = 0
    private var bufferLength = 0
    private val pw = PrintWriter(System.out)
    private fun Byte.isPrintable() = this in 33..126
    private fun Byte.isNumeric() = this in '0'.toByte()..'9'.toByte()
    private fun Byte.toNumVal() =
        if (this.isNumeric()) this - '0'.toByte() else error(this.toString() + " is not numeric")

    private fun hasNextByte(): Boolean {
        return if (pointer < bufferLength) true else {
            pointer = 0
            bufferLength = input.read(buffer)
            bufferLength > 0
        }
    }

    private fun readByte(): Byte = if (hasNextByte()) buffer[pointer++] else -1
    private fun skipUnprintable() = run { while (hasNextByte() && !buffer[pointer].isPrintable()) pointer++ }
    private fun hasNext(): Boolean = run { skipUnprintable() }.run { hasNextByte() }
    private fun hasNextOrError() = if (!hasNext()) error("has no next element.") else Unit

    fun readString(): String {
        hasNextOrError()
        val sb = StringBuilder()
        var b = readByte()
        while (b.isPrintable()) {
            sb.appendCodePoint(b.toInt())
            b = readByte()
        }
        return sb.toString()
    }

    fun readLong(): Long {
        hasNextOrError()
        var n = 0L
        var negative = false
        var b = readByte()
        if (b == '-'.toByte()) {
            negative = true
            b = readByte()
        }
        if (!b.isNumeric()) error(b.toString() + " is not numeric.")
        while (true) {
            when {
                b.isNumeric() -> n = n * 10 + b.toNumVal()
                b.toInt() == -1 || !b.isPrintable() -> return if (negative) -n else n
                else -> error("failed to parse. [n=" + n + ", b=" + b + "]")
            }
            b = readByte()
        }
    }

    fun readInt() = readLong()
        .let { if (it in Int.MIN_VALUE..Int.MAX_VALUE) it.toInt() else error(it.toString() + " is not in range of Int.") }

    fun readDouble(): Double {
        var n = 0.0
        var div = 1.0
        var negative = false
        var b = readByte()
        if (b == '-'.toByte()) {
            negative = true
            b = readByte()
        }
        do n = n * 10 + b.toNumVal()
        while (run { b = readByte() }.run { b.isNumeric() })
        if (b == '.'.toByte()) {
            while (run { b = readByte() }.run { b.isNumeric() })
                n += b.toNumVal() / (run { div *= 10 }.run { div })
        }
        return if (negative) -n else n
    }

    fun readStringList(size: Int) = readList(size) { readString() }
    fun readIntList(size: Int) = readList(size) { readInt() }
    fun readLongList(size: Int) = readList(size) { readLong() }
    fun readDoubleList(size: Int) = readList(size) { readDouble() }
    fun readIntArray(size: Int) = IntArray(size) { readInt() }
    fun readLongArray(size: Int) = LongArray(size) { readLong() }
    fun readDoubleArray(size: Int) = DoubleArray(size) { readDouble() }
    inline fun <reified T> readArray(size: Int, init: () -> T) = Array(size) { init() }
    inline fun <T> readList(size: Int, init: () -> T) = List(size) { init() }
    fun println() = pw.println()
    fun print(o: Any?) = pw.print(o)
    fun println(o: Any?) = pw.println(o)
    fun exec(code: IO_abc167e.() -> Unit) = run { code() }.run { pw.flush() }
}
// endregion