Problem:
Score : 500 points

Problem Statement

We have a grid of squares with N rows and M columns. Let (i, j) denote the square at the i-th row from the top and j-th column from the left. We will choose K of the squares and put a piece on each of them.

If we place the K pieces on squares (x_1, y_1), (x_2, y_2), ..., and (x_K, y_K), the cost of this arrangement is computed as:

\sum_{i=1}^{K-1} \sum_{j=i+1}^K (|x_i - x_j| + |y_i - y_j|)

Find the sum of the costs of all possible arrangements of the pieces. Since this value can be tremendous, print it modulo 10^9+7.

We consider two arrangements of the pieces different if and only if there is a square that contains a piece in one of the arrangements but not in the other.

Constraints

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

2 \leq K \leq N \times M

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M K

Output

Print the sum of the costs of all possible arrangements of the pieces, modulo 10^9+7.

Sample Input 1

2 2 2

Sample Output 1

8

There are six possible arrangements of the pieces, as follows:

((1,1),(1,2)), with the cost |1-1|+|1-2| = 1

((1,1),(2,1)), with the cost |1-2|+|1-1| = 1

((1,1),(2,2)), with the cost |1-2|+|1-2| = 2

((1,2),(2,1)), with the cost |1-2|+|2-1| = 2

((1,2),(2,2)), with the cost |1-2|+|2-2| = 1

((2,1),(2,2)), with the cost |2-2|+|1-2| = 1

The sum of these costs is 8.

Sample Input 2

4 5 4

Sample Output 2

87210

Sample Input 3

100 100 5000

Sample Output 3

817260251

Be sure to print the sum modulo 10^9+7.

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

import java.lang.ArithmeticException
import java.lang.IllegalArgumentException

val MOD = 1000000007L

val fact = Array(200010) { ModInt(1, MOD) }
val invfact = Array(200010) { ModInt(1, MOD) }

class ModInt (value: Long, val mod: Long) {
    init {
        if (mod <= 0) {
            throw IllegalArgumentException("ModInt cannot be created for non-positive mod: ${mod}")
        }
    }

    val value = (value % mod + mod) % mod

    private fun assertSameMod(other: ModInt) {
        if (mod != other.mod) {
            throw IllegalArgumentException(
                "You cannot operate summation, subtraction and multiplication for ModInts with different mods: $mod, ${other.mod}"
            )
        }
    }

    operator fun unaryMinus(): ModInt {
        return ModInt(mod - value, mod)
    }

    operator fun plus(other: ModInt): ModInt {
        assertSameMod(other)

        return ModInt((value + other.value) % mod, mod)
    }

    operator fun plus(other: Long): ModInt {
        return plus(ModInt(other, mod))
    }

    operator fun minus(other: ModInt): ModInt {
        assertSameMod(other)

        return plus(-other)
    }

    operator fun minus(other: Long): ModInt {
        return minus(ModInt(-other, mod))
    }

    operator fun times(other: ModInt): ModInt {
        assertSameMod(other)

        return ModInt((value * other.value) % mod, mod)
    }

    operator fun times(other: Long): ModInt {
        return times(ModInt(other, mod))
    }

    fun pow(k: Long): ModInt {
        var res = 1L
        var a = value
        var l = k

        while (l > 0) {
            if ((l and 1L) == 1L) {
                res = (res * a) % mod
            }

            a = a * a % mod
            l /= 2L
        }

        return ModInt(res, mod)
    }

    fun inv(): ModInt {
        return pow(mod - 2)
    }

    operator fun div(other: ModInt): ModInt {
        assertSameMod(other)
        if (other.value == 0L) {
            throw ArithmeticException()
        }

        return times(other.inv())
    }

    operator fun div(other: Long): ModInt {
        return div(ModInt(other, mod))
    }
}

fun comb(n: Long, m: Long): ModInt {
    if ( n < m )
        return ModInt(0L, MOD)

    return fact[n.toInt()] * invfact[(n - m).toInt()] * invfact[m.toInt()]
}

fun f(n: Long, m: Long): ModInt {
    var res = ModInt(0L, MOD)
    val p = comb(n * m, 2).inv()

    for (i in 1L until n) {
        res += ModInt(n - i, MOD) * i * m * m * p
    }

    return res
}

fun main(args: Array<String>) {
    val (N, M, K) = readLine()!!.split(" ").map { s -> s.toLong() }

    for(i in 1 until 200010) {
        fact[i] = fact[i - 1] * i.toLong()
        invfact[i] = invfact[i - 1] / i.toLong()
    }

    val a = ModInt(K, MOD) * (K - 1) / 2L
    val b = f(N, M) * a
    val c = f(M, N) * a

    val res = (b + c) * comb(N * M, K)

    println(res.value)
}