Find the sum of the costs of all possible arrangements of the cells
Given two integers N and M. At each operation, choose K cells of a 2D grid of size N * M and arrange them. If we choose the K cells (x1, y1), (x2, y2), …, and (xK, yK) then the cost of this arrangement is computed as ?i=1K-1 ?j=i+1K (|xi – xj| + |yi – yj|). The task is to find the sum of the costs of all possible arrangements of the cells. The answer can be very large so print the answer modulo 109 + 7
Examples:
Input: N = 2, M = 2, K = 2
Output: 8
((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
Input: N = 4, M = 5, N = 4
Output: 87210
Approach: Problem is to find the sum of the Manhattan distance when choosing K cells out of the N-M cells. Since the expression is clearly independent of X and Y, find the sum of the absolute values of the difference of X and the sum of the absolute values of the difference of Y respectively. Consider the difference in X. When a certain combination of 2 squares is fixed, since these differences contribute 1 degree each time when selecting K – 2 cells from other than these, it is possible to fix this pair N * M – 2CK – 2. Furthermore, since the difference is 0 if X is the same, assuming X is different, there is a way to choose 2 squares so that the absolute value of the difference in X is d ((N – d) * M2). If this is added to all d, you will get an answer about X. As for Y, N and M can be solved interchangeably, this problem can be solved in O(N * M).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 100005
#define mod (int)(1e9 + 7)
int factorial[N], modinverse[N];
int power( int a, int m1)
{
if (m1 == 0)
return 1;
else if (m1 == 1)
return a;
else if (m1 == 2)
return (1LL * a * a) % mod;
else if (m1 & 1)
return (1LL * a
* power(power(a, m1 / 2), 2))
% mod;
else
return power(power(a, m1 / 2), 2) % mod;
}
void factorialfun()
{
factorial[0] = 1;
for ( int i = 1; i < N; i++)
factorial[i] = (1LL * factorial[i - 1]
* i)
% mod;
}
void modinversefun()
{
modinverse[N - 1]
= power(factorial[N - 1], mod - 2) % mod;
for ( int i = N - 2; i >= 0; i--)
modinverse[i] = (1LL * modinverse[i + 1]
* (i + 1))
% mod;
}
int binomial( int n, int r)
{
if (r > n)
return 0;
int a = (1LL * factorial[n]
* modinverse[n - r])
% mod;
a = (1LL * a * modinverse[r]) % mod;
return a;
}
int arrange( int n, int m, int k)
{
factorialfun();
modinversefun();
long long ans = 0;
for ( int i = 1; i < n; i++)
ans += (1LL * i * (n - i) * m * m) % mod;
for ( int i = 1; i < m; i++)
ans += (1LL * i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2, k - 2)) % mod;
return ( int )ans;
}
int main()
{
int n = 2, m = 2, k = 2;
cout << arrange(n, m, k);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int N = 20 ;
static int mod = 1000000007 ;
static int []factorial = new int [N];
static int []modinverse = new int [N];
static int power( int a, int m1)
{
if (m1 == 0 )
return 1 ;
else if (m1 == 1 )
return a;
else if (m1 == 2 )
return (a * a) % mod;
else if ((m1 & 1 ) != 0 )
return (a * power(power(a, m1 / 2 ), 2 )) % mod;
else
return power(power(a, m1 / 2 ), 2 ) % mod;
}
static void factorialfun()
{
factorial[ 0 ] = 1 ;
for ( int i = 1 ; i < N; i++)
factorial[i] = (factorial[i - 1 ] * i) % mod;
}
static void modinversefun()
{
modinverse[N - 1 ] = power(factorial[N - 1 ],
mod - 2 ) % mod;
for ( int i = N - 2 ; i >= 0 ; i--)
modinverse[i] = (modinverse[i + 1 ] *
(i + 1 )) % mod;
}
static int binomial( int n, int r)
{
if (r > n)
return 0 ;
int a = (factorial[n] *
modinverse[n - r]) % mod;
a = (a * modinverse[r]) % mod;
return a;
}
static int arrange( int n, int m, int k)
{
factorialfun();
modinversefun();
int ans = 0 ;
for ( int i = 1 ; i < n; i++)
ans += (i * (n - i) * m * m) % mod;
ans = 8 ;
for ( int i = 1 ; i < m; i++)
ans += (i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2 ,
k - 2 )) % mod + 8 ;
return ans;
}
public static void main(String []args)
{
int n = 2 , m = 2 , k = 2 ;
System.out.println(arrange(n, m, k));
}
}
|
Python3
N = 100005
mod = ( int )( 1e9 + 7 )
factorial = [ 0 ] * N;
modinverse = [ 0 ] * N;
def power(a, m1) :
if (m1 = = 0 ) :
return 1 ;
elif (m1 = = 1 ) :
return a;
elif (m1 = = 2 ) :
return (a * a) % mod;
elif (m1 & 1 ) :
return (a * power(power(a, m1 / / 2 ), 2 )) % mod;
else :
return power(power(a, m1 / / 2 ), 2 ) % mod;
def factorialfun() :
factorial[ 0 ] = 1 ;
for i in range ( 1 , N) :
factorial[i] = (factorial[i - 1 ] * i) % mod;
def modinversefun() :
modinverse[N - 1 ] = power(factorial[N - 1 ],
mod - 2 ) % mod;
for i in range (N - 2 , - 1 , - 1 ) :
modinverse[i] = (modinverse[i + 1 ] *
(i + 1 )) % mod;
def binomial(n, r) :
if (r > n) :
return 0 ;
a = (factorial[n] * modinverse[n - r]) % mod;
a = (a * modinverse[r]) % mod;
return a;
def arrange(n, m, k) :
factorialfun();
modinversefun();
ans = 0 ;
for i in range ( 1 , n) :
ans + = ( i * (n - i) * m * m) % mod;
for i in range ( 1 , m) :
ans + = ( i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2 , k - 2 )) % mod;
return int (ans);
if __name__ = = "__main__" :
n = 2 ; m = 2 ; k = 2 ;
print (arrange(n, m, k));
|
C#
using System;
class GFG
{
static int N = 20;
static int mod = 1000000007;
static int []factorial = new int [N];
static int []modinverse = new int [N];
static int power( int a, int m1)
{
if (m1 == 0)
return 1;
else if (m1 == 1)
return a;
else if (m1 == 2)
return (a * a) % mod;
else if ((m1 & 1) != 0)
return (a * power(power(
a, m1 / 2), 2)) % mod;
else
return power(power(a, m1 / 2), 2) % mod;
}
static void factorialfun()
{
factorial[0] = 1;
for ( int i = 1; i < N; i++)
factorial[i] = (factorial[i - 1] * i) % mod;
}
static void modinversefun()
{
modinverse[N - 1] = power(factorial[N - 1],
mod - 2) % mod;
for ( int i = N - 2; i >= 0; i--)
modinverse[i] = (modinverse[i + 1] *
(i + 1)) % mod;
}
static int binomial( int n, int r)
{
if (r > n)
return 0;
int a = (factorial[n] *
modinverse[n - r]) % mod;
a = (a * modinverse[r]) % mod;
return a;
}
static int arrange( int n, int m, int k)
{
factorialfun();
modinversefun();
int ans = 0;
for ( int i = 1; i < n; i++)
ans += (i * (n - i) * m * m) % mod;
ans = 8;
for ( int i = 1; i < m; i++)
ans += (i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2,
k - 2)) % mod + 8;
return ans;
}
public static void Main(String []args)
{
int n = 2, m = 2, k = 2;
Console.WriteLine(arrange(n, m, k));
}
}
|
Javascript
<script>
let N = 20;
let mod = 1000000007;
let factorial = new Array(N);
factorial.fill(0);
let modinverse = new Array(N);
modinverse.fill(0);
function power(a, m1)
{
if (m1 == 0)
return 1;
else if (m1 == 1)
return a;
else if (m1 == 2)
return (a * a) % mod;
else if ((m1 & 1) != 0)
return (a *
power(power(a, parseInt(m1 / 2, 10)), 2)) % mod;
else
return power(power(a, parseInt(m1 / 2, 10)), 2) % mod;
}
function factorialfun()
{
factorial[0] = 1;
for (let i = 1; i < N; i++)
factorial[i] = (factorial[i - 1] * i) % mod;
}
function modinversefun()
{
modinverse[N - 1] = power(factorial[N - 1],
mod - 2) % mod;
for (let i = N - 2; i >= 0; i--)
modinverse[i] = (modinverse[i + 1] *
(i + 1)) % mod;
}
function binomial(n, r)
{
if (r > n)
return 0;
let a = (factorial[n] *
modinverse[n - r]) % mod;
a = (a * modinverse[r]) % mod;
return a;
}
function arrange(n, m, k)
{
factorialfun();
modinversefun();
let ans = 0;
for (let i = 1; i < n; i++)
ans += (i * (n - i) * m * m) % mod;
ans = 8;
for (let i = 1; i < m; i++)
ans += (i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2,
k - 2) * 0) % mod + 8;
return ans;
}
let n = 2, m = 2, k = 2;
document.write(arrange(n, m, k));
</script>
|
Time Complexity: O(max(M,N)).
Auxiliary Space: O(100005).
Last Updated :
13 Feb, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...