Language: C++

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sz(a) a.size()
#define all(a) a.begin(),a.end()
#define F first
#define S second
#define pb push_back
#define eb emplace_back
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;


string to_string(string s) {
	return '"' + s + '"';
}

string to_string(const char* s) {
	return to_string((string) s);
}

string to_string(bool b) {
	return (b ? "true" : "false");
}

string to_string(char ch) {
	return string("'")+ch+string("'");
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
	return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <class InputIterator>
string to_string (InputIterator first, InputIterator last) {
	bool start = true;
	string res = "{";
	while (first!=last) {
		if (!start) {
			res += ", ";
		}
		start = false;
		res += to_string(*first);
		++first;
	}
	res += "}";
	return res;
}

template <typename A>
string to_string(A v) {
	bool first = true;
	string res = "{";
	for (const auto &x : v) {
		if (!first) {
			res += ", ";
		}
		first = false;
		res += to_string(x);
	}
	res += "}";
	return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	cerr << " " << to_string(H);
	debug_out(T...);
}

template <typename A, typename B>
istream& operator>>(istream& input,pair<A,B>& x){
	input>>x.F>>x.S;
	return input;
}

template <typename A>
istream& operator>>(istream& input,vector<A>& x){
	for(auto& i:x)
		input>>i;
	return input;
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif



const int mod=1e9+7;

int mul(int a,int b)
{
	return (a*1ll*b)%mod;
	}
	
void add(int &a,int b)
{
	a+=b;
	if(a>=mod)a-=mod;
	}
int powz(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1)res=mul(res,a);
		b/=2;
		a=mul(a,a);
		}
	return res;
	}

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N=300005;

int Cr(int n, int r, int p) 
{ 
    // The array C is going to store last row of 
    // pascal triangle at the end. And last entry 
    // of last row is nCr 
    int C[r+1]; 
    memset(C, 0, sizeof(C)); 
  
    C[0] = 1; // Top row of Pascal Triangle 
  
    // One by constructs remaining rows of Pascal 
    // Triangle from top to bottom 
    for (int i = 1; i <= n; i++) 
    { 
        // Fill entries of current row using previous 
        // row values 
        for (int j = min(i, r); j > 0; j--) 
  
            // nCj = (n-1)Cj + (n-1)C(j-1); 
            C[j] = (C[j] + C[j-1])%p; 
    } 
    return C[r]; 
} 
   
void solve(){
ll n,m,k;
cin>>n>>m>>k;
ll sum=0,rev=0,cur=0,cnt=0;
for(ll j=1;j<=n;j++)
{
for(ll i=1;i<=m;i++)
{
	cur+=(j)*(cnt)-rev;
	rev+=j;
	
	cnt++;
	}
}
	sum+=cur;
	if(sum>=mod)sum-=mod;
	rev=0,cur=0,cnt=0;
for(ll j=1;j<=m;j++)
{
for(ll i=1;i<=n;i++)
{
	cur+=(j)*(cnt)-rev;
	rev+=j;
	
	cnt++;
	}
}
	sum+=cur;
	if(sum>=mod)sum-=mod;
	ll comb=1;
	for(int i=1;i<=k-2;i++){comb*=powz(i,mod-2);comb%=mod;}
	for(int i=1;i<=n*m-2-k;i++){comb*=powz(i,mod-2);comb%=mod;}
	for(int i=1;i<=n*m-2;i++){comb*=i;comb%=mod;}
	cout<<(sum*Cr(n*m-2,k-2,mod))%mod;
}
	

int main()
{   
    ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int tc=1;
	//cin>>tc;
	
    for(int i=0;i<tc;i++)
	{
		
        solve();
		}
	
	}
/* Intuition > Logic 
 * If you are not confident please dont submit
 * When you feel like Quitting: Remember why you started
 * Game Theory == Skip
 * If n== 1e18 apply binary or Matrix expo

 *  I see those tears in your eyes
   I feel so helpless inside
   Oh love, there's no need to hide
   Just let me love you when your heart is tired
   Cold hands, red eyes
   Packed your bags at midnight
   They've been there for weeks
   You don't know what goodbye means
   Just roll up a cigarette
   Just forget about this mess
   Waiting on the sidelines
   From the sidelines
 */
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sz(a) a.size()
#define all(a) a.begin(),a.end()
#define F first
#define S second
#define pb push_back
#define eb emplace_back
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;


string to_string(string s) {
	return '"' + s + '"';
}

string to_string(const char* s) {
	return to_string((string) s);
}

string to_string(bool b) {
	return (b ? "true" : "false");
}

string to_string(char ch) {
	return string("'")+ch+string("'");
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
	return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <class InputIterator>
string to_string (InputIterator first, InputIterator last) {
	bool start = true;
	string res = "{";
	while (first!=last) {
		if (!start) {
			res += ", ";
		}
		start = false;
		res += to_string(*first);
		++first;
	}
	res += "}";
	return res;
}

template <typename A>
string to_string(A v) {
	bool first = true;
	string res = "{";
	for (const auto &x : v) {
		if (!first) {
			res += ", ";
		}
		first = false;
		res += to_string(x);
	}
	res += "}";
	return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	cerr << " " << to_string(H);
	debug_out(T...);
}

template <typename A, typename B>
istream& operator>>(istream& input,pair<A,B>& x){
	input>>x.F>>x.S;
	return input;
}

template <typename A>
istream& operator>>(istream& input,vector<A>& x){
	for(auto& i:x)
		input>>i;
	return input;
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif



const int mod=1e9+7;

int mul(int a,int b)
{
	return (a*1ll*b)%mod;
	}
	
void add(int &a,int b)
{
	a+=b;
	if(a>=mod)a-=mod;
	}
int powz(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1)res=mul(res,a);
		b/=2;
		a=mul(a,a);
		}
	return res;
	}

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N=300005;

int Cr(int n, int r, int p) 
{ 
    // The array C is going to store last row of 
    // pascal triangle at the end. And last entry 
    // of last row is nCr 
    int C[r+1]; 
    memset(C, 0, sizeof(C)); 
  
    C[0] = 1; // Top row of Pascal Triangle 
  
    // One by constructs remaining rows of Pascal 
    // Triangle from top to bottom 
    for (int i = 1; i <= n; i++) 
    { 
        // Fill entries of current row using previous 
        // row values 
        for (int j = min(i, r); j > 0; j--) 
  
            // nCj = (n-1)Cj + (n-1)C(j-1); 
            C[j] = (C[j] + C[j-1])%p; 
    } 
    return C[r]; 
} 
   
void solve(){
ll n,m,k;
cin>>n>>m>>k;
ll sum=0,rev=0,cur=0,cnt=0;
for(ll j=1;j<=n;j++)
{
for(ll i=1;i<=m;i++)
{
	cur+=(j)*(cnt)-rev;
	rev+=j;
	
	cnt++;
	}
}
	sum+=cur;
	if(sum>=mod)sum-=mod;
	rev=0,cur=0,cnt=0;
for(ll j=1;j<=m;j++)
{
for(ll i=1;i<=n;i++)
{
	cur+=(j)*(cnt)-rev;
	rev+=j;
	
	cnt++;
	}
}
	sum+=cur;
	if(sum>=mod)sum-=mod;
	ll comb=1;
	for(int i=1;i<=k-2;i++){comb*=powz(i,mod-2);comb%=mod;}
	for(int i=1;i<=n*m-2-k;i++){comb*=powz(i,mod-2);comb%=mod;}
	for(int i=1;i<=n*m-2;i++){comb*=i;comb%=mod;}
	cout<<(sum*Cr(n*m-2,k-2,mod))%mod;
}
	

int main()
{   
    ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int tc=1;
	//cin>>tc;
	
    for(int i=0;i<tc;i++)
	{
		
        solve();
		}
	
	}
/* Intuition > Logic 
 * If you are not confident please dont submit
 * When you feel like Quitting: Remember why you started
 * Game Theory == Skip
 * If n== 1e18 apply binary or Matrix expo

 *  I see those tears in your eyes
   I feel so helpless inside
   Oh love, there's no need to hide
   Just let me love you when your heart is tired
   Cold hands, red eyes
   Packed your bags at midnight
   They've been there for weeks
   You don't know what goodbye means
   Just roll up a cigarette
   Just forget about this mess
   Waiting on the sidelines
   From the sidelines
 */


Compiler output:
a.cc:242:8: error: redefinition of 'std::string to_string(std::string)'
  242 | string to_string(string s) {
      |        ^~~~~~~~~
a.cc:20:8: note: 'std::string to_string(std::string)' previously defined here
   20 | string to_string(string s) {
      |        ^~~~~~~~~
a.cc:246:8: error: redefinition of 'std::string to_string(const char*)'
  246 | string to_string(const char* s) {
      |        ^~~~~~~~~
a.cc:24:8: note: 'std::string to_string(const char*)' previously defined here
   24 | string to_string(const char* s) {
      |        ^~~~~~~~~
a.cc:250:8: error: redefinition of 'std::string to_string(bool)'
  250 | string to_string(bool b) {
      |        ^~~~~~~~~
a.cc:28:8: note: 'std::string to_string(bool)' previously defined here
   28 | string to_string(bool b) {
      |        ^~~~~~~~~
a.cc:254:8: error: redefinition of 'std::string to_string(char)'
  254 | string to_string(char ch) {
      |        ^~~~~~~~~
a.cc:32:8: note: 'std::string to_string(char)' previously defined here
   32 | string to_string(char ch) {
      |        ^~~~~~~~~
a.cc:259:8: error: redefinition of 'template<class A, class B> std::string to_string(std::pair<_T1, _T2>)'
  259 | string to_string(pair<A, B> p) {
      |        ^~~~~~~~~
a.cc:37:8: note: 'template<class A, class B> std::string to_string(std::pair<_T1, _T2>)' previously declared here
   37 | string to_string(pair<A, B> p) {
      |        ^~~~~~~~~
a.cc:264:8: error: redefinition of 'template<class InputIterator> std::string to_string(InputIterator, InputIterator)'
  264 | string to_string (InputIterator first, InputIterator last) {
      |        ^~~~~~~~~
a.cc:42:8: note: 'template<class InputIterator> std::string to_string(InputIterator, InputIterator)' previously declared here
   42 | string to_string (InputIterator first, InputIterator last) {
      |        ^~~~~~~~~
a.cc:280:8: error: redefinition of 'template<class A> std::string to_string(A)'
  280 | string to_string(A v) {
      |        ^~~~~~~~~
a.cc:58:8: note: 'template<class A> std::string to_string(A)' previously declared here
   58 | string to_string(A v) {
      |        ^~~~~~~~~
a.cc:294:6: error: redefinition of 'void debug_out()'
  294 | void debug_out() { cerr << endl; }
      |      ^~~~~~~~~
a.cc:72:6: note: 'void debug_out()' previously defined here
   72 | void debug_out() { cerr << endl; }
      |      ^~~~~~~~~
a.cc:297:6: error: redefinition of 'template<class Head, class ... Tail> void debug_out(Head, Tail ...)'
  297 | void debug_out(Head H, Tail... T) {
      |      ^~~~~~~~~
a.cc:75:6: note: 'template<class Head, class ... Tail> void debug_out(Head, Tail ...)' previously declared here
   75 | void debug_out(Head H, Tail... T) {
      |      ^~~~~~~~~
a.cc:303:10: error: redefinition of 'template<class A, class B> std::istream& operator>>(std::istream&, std::pair<_T1, _T2>&)'
  303 | istream& operator>>(istream& input,pair<A,B>& x){
      |          ^~~~~~~~
a.cc:81:10: note: 'template<class A, class B> std::istream& operator>>(std::istream&, std::pair<_T1, _T2>&)' previously declared here
   81 | istream& operator>>(istream& input,pair<A,B>& x){
      |          ^~~~~~~~
a.cc:309:10: error: redefinition of 'template<class A> std::istream& operator>>(std::istream&, std::vector<_Tp>&)'
  309 | istream& operator>>(istream& input,vector<A>& x){
      |          ^~~~~~~~
a.cc:87:10: note: 'template<class A> std::istream& operator>>(std::istream&, std::vector<_Tp>&)' previously declared here
   87 | istream& operator>>(istream& input,vector<A>& x){
      |          ^~~~~~~~
a.cc:323:11: error: redefinition of 'const int mod'
  323 | const int mod=1e9+7;
      |           ^~~
a.cc:101:11: note: 'const int mod' previously defined here
  101 | const int mod=1e9+7;
      |           ^~~
a.cc:325:5: error: redefinition of 'int mul(int, int)'
  325 | int mul(int a,int b)
      |     ^~~
a.cc:103:5: note: 'int mul(int, int)' previously defined here
  103 | int mul(int a,int b)
      |     ^~~
a.cc:330:6: error: redefinition of 'void add(int&, int)'
  330 | void add(int &a,int b)
      |      ^~~
a.cc:108:6: note: 'void add(int&, int)' previously defined here
  108 | void add(int &a,int b)
      |      ^~~
a.cc:335:5: error: redefinition of 'int powz(int, int)'
  335 | int powz(int a,int b)
      |     ^~~~
a.cc:113:5: note: 'int powz(int, int)' previously defined here
  113 | int powz(int a,int b)
      |     ^~~~
a.cc:347:9: error: redefinition of 'std::mt19937 rng'
  347 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
      |         ^~~
a.cc:125:9: note: 'std::mt19937 rng' previously declared here
  125 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
      |         ^~~
a.cc:348:11: error: redefinition of 'const int N'
  348 | const int N=300005;
      |           ^
a.cc:126:11: note: 'const int N' previously defined here
  126 | const int N=300005;
      |           ^
a.cc:350:5: error: redefinition of 'int Cr(int, int, int)'
  350 | int Cr(int n, int r, int p)
      |     ^~
a.cc:128:5: note: 'int Cr(int, int, int)' previously defined here
  128 | int Cr(int n, int r, int p)
      |     ^~
a.cc:374:6: error: redefinition of 'void solve()'
  374 | void solve(){
      |      ^~~~~
a.cc:152:6: note: 'void solve()' previously defined here
  152 | void solve(){
      |      ^~~~~
a.cc:411:5: error: redefinition of 'int main()'
  411 | int main()
      |     ^~~~
a.cc:189:5: note: 'int main()' previously defined here
  189 | int main()
      |     ^~~~