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-1j=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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
#define N 100005
#define mod (int)(1e9 + 7)
  
// To store the factorials and factorial
// mod inverse of the numbers
int factorial[N], modinverse[N];
  
// Function to return (a ^ m1) % mod
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;
}
  
// Function to find the factorials
// of all the numbers
void factorialfun()
{
    factorial[0] = 1;
    for (int i = 1; i < N; i++)
        factorial[i] = (1LL * factorial[i - 1]
                        * i)
                       % mod;
}
  
// Function to find factorial mod
// inverse of all the numbers
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;
}
  
// Function to return nCr
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;
}
  
// Function to return the sum of the costs of
// all the possible arrangements of the cells
int arrange(int n, int m, int k)
{
    factorialfun();
    modinversefun();
  
    long long ans = 0;
  
    // For all possible X's
    for (int i = 1; i < n; i++)
        ans += (1LL * i * (n - i) * m * m) % mod;
  
    // For all possible Y's
    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;
}
  
// Driver code
int main()
{
    int n = 2, m = 2, k = 2;
  
    cout << arrange(n, m, k);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{
static int N = 20;
static int mod = 1000000007;
  
// To store the factorials and factorial
// mod inverse of the numbers
static int []factorial = new int[N];
static int []modinverse = new int[N];
  
// Function to return (a ^ m1) % mod
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;
}
  
// Function to find the factorials
// of all the numbers
static void factorialfun()
{
    factorial[0] = 1;
    for (int i = 1; i < N; i++)
        factorial[i] = (factorial[i - 1] * i) % mod;
}
  
// Function to find factorial mod
// inverse of all the numbers
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;
}
  
// Function to return nCr
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;
}
  
// Function to return the sum of the costs of
// all the possible arrangements of the cells
static int arrange(int n, int m, int k)
{
    factorialfun();
    modinversefun();
  
    int ans = 0;
  
    // For all possible X's
    for (int i = 1; i < n; i++)
        ans += (i * (n - i) * m * m) % mod;
  
    // For all possible Y's
    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;
}
  
// Driver code
public static void main(String []args)
{
    int n = 2, m = 2, k = 2;
  
    System.out.println(arrange(n, m, k));
}
}
  
// This code is contributed by Surendra_Gangwar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
N = 100005
mod = (int)(1e9 + 7
  
# To store the factorials and factorial 
# mod inverse of the numbers 
factorial = [0] * N;
modinverse = [0] * N; 
  
# Function to return (a ^ m1) % mod 
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; 
  
# Function to find the factorials 
# of all the numbers 
def factorialfun() :
  
    factorial[0] = 1
    for i in range(1, N) : 
        factorial[i] = (factorial[i - 1] * i) % mod; 
  
# Function to find factorial mod 
# inverse of all the numbers 
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; 
  
# Function to return nCr 
def binomial(n, r) :
  
    if (r > n) :
        return 0
  
    a = (factorial[n] * modinverse[n - r]) % mod; 
  
    a = (a * modinverse[r]) % mod; 
    return a; 
  
# Function to return the sum of the costs of 
# all the possible arrangements of the cells 
def arrange(n, m, k) :
  
    factorialfun(); 
    modinversefun(); 
  
    ans = 0
  
    # For all possible X's 
    for i in range(1, n) :
        ans += ( i * (n - i) * m * m) % mod; 
  
    # For all possible Y's 
    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); 
  
# Driver code 
if __name__ == "__main__"
  
    n = 2; m = 2; k = 2
  
    print(arrange(n, m, k)); 
  
# This code is contributed by AnkitRai01

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GFG
{
static int N = 20;
static int mod = 1000000007;
  
// To store the factorials and factorial
// mod inverse of the numbers
static int []factorial = new int[N];
static int []modinverse = new int[N];
  
// Function to return (a ^ m1) % mod
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;
}
  
// Function to find the factorials
// of all the numbers
static void factorialfun()
{
    factorial[0] = 1;
    for (int i = 1; i < N; i++)
        factorial[i] = (factorial[i - 1] * i) % mod;
}
  
// Function to find factorial mod
// inverse of all the numbers
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;
}
  
// Function to return nCr
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;
}
  
// Function to return the sum of the costs of
// all the possible arrangements of the cells
static int arrange(int n, int m, int k)
{
    factorialfun();
    modinversefun();
  
    int ans = 0;
  
    // For all possible X's
    for (int i = 1; i < n; i++)
        ans += (i * (n - i) * m * m) % mod;
  
    // For all possible Y's
    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;
}
  
// Driver code
public static void Main(String []args)
{
    int n = 2, m = 2, k = 2;
  
    Console.WriteLine(arrange(n, m, k));
}
}
  
// This code is contributed by PrinciRaj1992

chevron_right


Output:

8

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.