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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.util.*;
public class Main {
	static long M = 1000000007;
	public static void main(String[] args) {
		for(int i = 0; i < 200001; i++) fac(i);
		Scanner seer = new Scanner(System.in);
		int n = seer.nextInt();
		int m = seer.nextInt();
		int k = seer.nextInt();
		//todos contra todos
		long[] calc = new long[n];
		for(int i = 1; i < m; i++){
			calc[0] = sum(calc[0], mult(i, m-i));
		}
		for(int i = 1; i < n; i++){
			calc[i] = sum(calc[i-1], mult(calc[0], 2), mult(m, m, i));
		}
		long tot = 0;
		for(long c: calc) tot = sum(tot, c);
		
		System.out.println(mult(tot, comb(n*m-2, k-2)));
	}
	static long[] fac = new long[200001];
	static long[] invfac = new long[200001];
	static long fac(int n){
		if(n == 0) return fac[0] = 1;
		else if(fac[n] > 0) return fac[n];
		else return fac[n] = mult(n, fac(n-1));
	}
	static long invfac(int n){
		if(invfac[n] > 0) return invfac[n];
		else return invfac[n] = inv(fac[n]);
	}
	static long inv(long a){
		return (gcdex(a, M).r + M) % M;
	}
	static Pair gcdex(long a, long b){
		if(b > a) return gcdex(b, a).invert();
		else if(b == 0) return new Pair(1, 0);
		else{
			Pair p = gcdex(b, a%b); //p.r * b + p.s * (a - b(a/b)) = 1
			return new Pair(p.s, p.r - p.s*(a/b));
		}
	}
	static class Pair{
		long r, s;
		public Pair(long r, long s){
			this.r = r; this.s = s;
		}
		public Pair invert(){
			return new Pair(s, r);
		}
	}
	static long comb(int n, int k){
		return mult(fac(n), invfac(k), invfac(n-k));
	}
	static long mult(long... ls){
		long res = 1;
		for(long a: ls){
			res = (res * a) % M;
		}
		return res;
	}
	static long sum(long... ls){
		long res = 0;
		for(long a: ls){
			res = (res + a) % M;
		}
		return res;
	}
}