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 JavaScript (node.js v5.12) (judge verdict: Accepted)

'use strict';
(function(input){
  input=input.trim().split(/\s+/).map(x=>x-0);
  const N=Math.min(input[0],input[1]);
  const M=Math.max(input[0],input[1]);
  const K=input[2];
  const E=1e9+7;
  
  function check(num){
    if(!Number.isSafeInteger(num)){
      console.log(num,'overFlow!');
    }
  }
  
  function multiply(a,b){
    var A=[(a-a%100000)/100000,a%100000];
    A[0]=(((A[0]*b)%E)*100000)%E;
    A[1]=(A[1]*b)%E
    return Math.round((((A[0]+A[1])%E)+E)%E);
  }
  
  var ans=0;
  
  for(let d=1;d<=N-1;d++){
    let A=(1/6)*(d+1)*(d+2)*(d+3);
    let B=((N-d-1)+(M-d-1))*(1/2)*(d+1)*(d+2);
    let C=(N-d-1)*(M-d-1)*(d+1);
    let D=(N-d)*M+(M-d)*N;
    A%=E;
    B%=E;
    C%=E;
    D%=E;
    ans+=multiply(((A+B+C)*2-D),d);
    //check(ans);
    ans=((ans%E)+E)%E;
  }
  
  for(let d=N;d<=M-1;d++){
    let A=(1/6)*(N)*(N+1)*(N+2);
    let B=(M-d-1)*(1/2)*(N)*(N+1);
    let C=0;
    let D=(M-d)*N;
    A%=E;
    B%=E;
    C%=E;
    D%=E;
    ans+=multiply(((A+B+C)*2-D),d);
    check(ans);
    ans=((ans%E)+E)%E;
  }
  
  for(let d=M;d<=N+M-2;d++){
    let a=N+M-1-d;
    let A=(1/6)*(a)*(a+1)*(a+2);
    let B=0;
    let C=0;
    let D=0;
    A%=E;
    B%=E;
    C%=E;
    D%=E;
    ans+=multiply(((A+B+C)*2-D),d);
    ans=((ans%E)+E)%E;
  }
  //console.log(ans);
  
  //ansに(N*M-2)C(K-2)をかける↓
  for(let i=0;i<K-2;i++){//まず分子のかけ算
    ans=multiply(ans,(N*M-2-i));
  }
  //console.log(ans);
  
  var denominator=1;
  for(let i=1;i<=K-2;i++){
    denominator=multiply(denominator,i);
  }
  //合同式でansをdenominatorで割る(ユークリッドの互除法の応用)↓
  const r=[E,denominator];
  //console.log(r);
  while(r[r.length-1]!==0){
    let A=r[r.length-2],B=r[r.length-1];
    let R=A%B;
    r.push(R);
  }
  r.pop();
  //console.log(r);
  const x=[1],y=[0];
  while(r.length>2){
    let q=(r[r.length-3]-r[r.length-1])/r[r.length-2];
    
    //r[-3]-q*r[-2]=r[-1]を1=x*r[-1]+y*r[-2]に代入。
    //1=x*(r[-3]-q*r[-2])+y*r[-2]=(y-qx)*r[-2]+x*r[-3];
    x.push((((y[y.length-1]-q*x[x.length-1])%E)+E)%E);
    y.push(x[x.length-2]);
    r.pop();
  }
  //console.log(x,y);
  const F=((x[x.length-1])%E+E)%E;
  //Fはdenominator*F+整数*E=1の解、すなわちmod.Eの世界でのdenominatorの「逆数」
  //2^53以内に計算を抑えるために10^5で割った商と余りに分けて計算
  ans=multiply(ans,F);
  console.log(ans);
})(require('fs').readFileSync('/dev/stdin','utf8'));