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 Rust (1.15.1) (judge verdict: Accepted)

use std::io::prelude::*;

fn input<T>() -> T
where
    T: std::str::FromStr,
{
    let stdin = std::io::stdin();
    let token: String = stdin
        .lock()
        .bytes()
        .map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().unwrap()
}

fn main() {
    let n: i64 = input();
    let m: i64 = input();
    let k: i64 = input();

    let mut xans = 0i64;
    for i in 1..m {
        xans += i * (m - i);
        xans %= MOD;
    }
    xans *= n * n;
    xans %= MOD;

    let mut yans = 0i64;
    for i in 1..n {
        yans += i * (n - i);
        yans %= MOD;
    }
    yans *= m * m;
    yans %= MOD;

    let comb = Combination::new(n * m);
    let mut ans = (xans + yans) % MOD;
    ans *= comb.combination(n * m - 2, k - 2);
    ans %= MOD;
    println!("{}", ans);
}

const MOD: i64 = 1000000007;

struct Combination {
    fact: Vec<i64>,
    ifact: Vec<i64>,
}

impl Combination {
    fn new(n: i64) -> Combination {
        let n = n as usize;
        let mut f = vec![0; n + 1];
        f[0] = 1;
        for i in 1..n + 1 {
            f[i] = f[i - 1] * i as i64 % MOD;
        }
        let mut invf = vec![0; n + 1];
        invf[n] = Combination::inverse(f[n]);
        for i in (1..n + 1).rev() {
            invf[i - 1] = invf[i] * i as i64 % MOD;
        }
        Combination {
            fact: f,
            ifact: invf,
        }
    }

    fn inverse(x: i64) -> i64 {
        Combination::power(x, MOD - 2)
    }

    fn power(x: i64, p: i64) -> i64 {
        if p == 0 {
            1
        } else if p % 2 == 0 {
            let t = Combination::power(x, p / 2);
            t * t % MOD
        } else {
            Combination::power(x, p - 1) * x % MOD
        }
    }

    fn combination(&self, n: i64, k: i64) -> i64 {
        if n < 0 || k < 0 || k > n {
            0
        } else {
            let (n, k) = (n as usize, k as usize);
            self.fact[n] * self.ifact[k] % MOD * self.ifact[n - k] % MOD
        }
    }
}