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: Time Limit Exceeded)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
#[allow(unused_imports)]
use itertools::Itertools;
#[allow(unused_imports)]
use num::*;
use proconio::input;
#[allow(unused_imports)]
use proconio::marker::*;
#[allow(unused_imports)]
use std::collections::*;

pub struct ModComb {
  max: usize,
  modulo: usize,
  fac: Vec<usize>,
  finv: Vec<usize>,
}

impl ModComb {
  pub fn new(max: usize, modulo: usize) -> Self {
    let mut fac = vec![0_usize; max + 1];
    let mut finv = vec![0_usize; max + 1];
    let mut inv = vec![0_usize; max + 1];
    fac[0] = 1;
    fac[1] = 1;
    finv[0] = 1;
    finv[1] = 1;
    inv[1] = 1;
    for i in 2..=max {
      fac[i] = (fac[i - 1] * i) % modulo;
      inv[i] = modulo - ((inv[modulo % i] * (modulo / i)) % modulo);
      finv[i] = (finv[i - 1] * inv[i]) % modulo;
    }
    Self {
      max,
      modulo,
      fac,
      finv,
    }
  }

  pub fn comb(&self, n: usize, k: usize) -> usize {
    if n > self.max {
      panic!();
    }
    if n < k {
      return 0;
    }
    (self.fac[n] * ((self.finv[k] * self.finv[n - k]) % self.modulo)) % self.modulo
  }
}

const MOD: usize = 1_000_000_007;

fn main() {
  input! {
    n: usize, m: usize, k: usize
  };

  let comb = ModComb::new(n * m, MOD);
  let mut res = 0;
  for i in 0..n - 1 {
    for j in i + 1..n {
      let d = j - i;
      res = (res + (d * m * m * comb.comb(n * m - 2, k - 2) % MOD)) % MOD;
    }
  }
  for i in 0..m - 1 {
    for j in i + 1..m {
      let d = j - i;
      res = (res + (d * n * n * comb.comb(n * m - 2, k - 2) % MOD)) % MOD;
    }
  }
  println!("{}", res);
}
*/

fn main() {
    let exe = "/tmp/bin0799D8CE";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";