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)

#![allow(dead_code)]

use std::io::{stdin, Read};

const MOD: u64 = 1000000007;

fn gcd(a: u64, b: u64) -> u64 {
    match b {
        0 => a,
        _ => gcd(b, a % b),
    }
}

fn powmod(base: u64, exp: u64, m: u64) -> u64 {
    let b: Vec<bool> = format!("{:b}", exp)
        .chars()
        .map(|x| x.to_digit(10).unwrap() != 0)
        .collect();
    let mut v = 1;
    for bi in b {
        v *= v;
        v %= m;
        if bi {
            v *= base;
            v %= m
        }
    }
    return v % m;
}

fn invmod(x: u64, m: u64) -> u64 {
    powmod(x, m - 2, m)
}

fn prime_factors(x: u64) -> Vec<u64> {
    let mut res = vec![];
    let mut y = x;
    let mut p = 2;
    let upper = (y as f64).sqrt() as u64;
    while y > 1 && p <= upper {
        match y % p {
            0 => {
                res.push(p);
                y /= p;
            }
            _ => {
                p += 1;
            }
        }
    }
    if y > 1 {
        res.push(y)
    }
    return res;
}

fn get_factorials(n: u64, m: u64) -> Vec<u64> {
    let mut res = vec![1];
    let mut cur = 1;
    for i in 1..(n + 1) {
        cur *= i;
        cur %= m;
        res.push(cur);
    }
    res
}

fn get_facinvs(n: u64, m: u64) -> Vec<u64> {
    let mut res = vec![1];
    let mut cur = 1;
    for i in 1..(n + 1) {
        cur *= invmod(i, m);
        cur %= m;
        res.push(cur);
    }
    res
}

fn combmod(a: u64, b: u64, m: u64, facts: &Vec<u64>, invs: &Vec<u64>) -> u64 {
    if a < b {
        0
    } else {
        (((facts[a as usize] * invs[b as usize]) % m) * invs[(a - b) as usize]) % m
    }
}

macro_rules! parse {
    ($iter: ident) => {
        $iter.next().unwrap().parse().unwrap()
    };
    ($iter: ident,2) => {
        (parse!($iter), parse!($iter))
    };
    ($iter: ident,3) => {
        (parse!($iter), parse!($iter), parse!($iter))
    };
    ($iter: ident,4) => {
        (parse!($iter), parse!($iter), parse!($iter), parse!($iter))
    };
    ($iter: ident, $n: ident) => {
        $iter.take($n).map(|e| e.parse().unwrap()).collect();
    };
}

fn solve(x: u64, y: u64, c: u64) -> u64 {
    (1..x)
        .map(|d| (d * ((((((x - d) * y) % MOD) * y) % MOD) * c) % MOD) % MOD)
        .fold(0, |a, b| (a + b) % MOD)
}

fn main() {
    let mut s = String::new();
    stdin().read_to_string(&mut s).unwrap();
    let mut iter = s.split_whitespace();
    let (n, m, k): (u64, u64, u64) = parse!(iter, 3);

    let facts = get_factorials(200001, MOD);
    let invs = get_facinvs(200001, MOD);
    let c = combmod(n * m - 2, k - 2, MOD, &facts, &invs);
    let mut res = solve(n, m, c) + solve(m, n, c);
    res %= MOD;
    println!("{}", res)
}