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)

fn main() {
    let (n,m,k) = {
        let v: Vec<usize> = read_vec();
        (v[0], v[1], v[2])
    };
    let fact = |n| (2..n+1).fold(F(1), |f, a| f * F(a as u64));
    let comb = fact(n*m-2) / fact(n*m-k) / fact(k-2);
    let solve = |n, m| {
        let mut res = F(0);
        let (h, w) = (F(n as u64), F(m as u64));
        for d in 1..n {
            let d = F(d as u64);
            res += d*(h-d);
        }
        res * comb * w * w
    };
    println!("{}", solve(n,m)+solve(m,n));
}
fn get_line() -> String {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).ok();
    buf.trim().to_owned()
}

fn read<T: std::str::FromStr>() -> T{
    get_line().parse().ok().unwrap()
}
fn read_vec<T: std::str::FromStr>() -> Vec<T>{
    get_line().split_whitespace()
        .map(|e| e.parse().ok().unwrap()).collect()
}
fn read_pair<T: std::str::FromStr + Copy>() -> (T,T){
    let v:Vec<T> = read_vec(); (v[0], v[1])
}

#[derive(Copy, Clone)]
struct F(u64);
const MOD:u64 = 1000000007;

impl F {
    pub fn new(n: i32) -> Self { F((MOD as i32 + n)as u64%MOD) }
    pub fn pow(self, mut exp: u32) -> Self {
        let mut base = self.0;
        let mut acc = 1;
        while exp > 1 {
            if (exp & 1) == 1 { acc *= base; acc %= MOD; }
            exp /= 2; base *= base; base %= MOD;
        }
        if exp == 1 { acc *= base; acc %= MOD; }
        F(acc)
    }
}
impl std::cmp::PartialEq for F {
    fn eq(&self, rhs: &Self) -> bool {self.0 == rhs.0}
}
impl std::fmt::Display for F {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

use std::ops::*;
impl Mul for F {
    type Output = Self;
    fn mul(self, rhs: Self) -> Self {F((self.0 * rhs.0)%MOD)}
}
impl MulAssign for F {
    fn mul_assign(&mut self, rhs: Self) {*self = F((self.0 * rhs.0)%MOD)}
}
impl Add for F {
    type Output = Self;
    fn add(self, rhs: Self) -> Self {F((self.0 + rhs.0)%MOD)}
}
impl AddAssign for F {
    fn add_assign(&mut self, rhs: Self) {*self = F((self.0 + rhs.0)%MOD)}
}
impl Neg for F {
    type Output = Self;
    fn neg(self) -> Self {if self.0==0 {F(0)} else {F(MOD-self.0)}}
}
impl Sub for F {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self {F((self.0 - rhs.0 + MOD)%MOD)}
}
impl SubAssign for F {
    fn sub_assign(&mut self, rhs: Self) {*self = F((self.0 - rhs.0 + MOD)%MOD)}
}
impl Div for F {
    type Output = Self;
    fn div(self, rhs: Self) -> Self {F(self.0 * rhs.pow(MOD as u32-2).0 %MOD)}
}
impl DivAssign for F {
    fn div_assign(&mut self, rhs: Self) {*self = F(self.0 * rhs.pow(MOD as u32-2).0 %MOD)}
}