There is a rectangular grid of size m × n containing k identical pieces.
Return the sum of Manhattan distances between every pair of pieces over all
valid arrangements of pieces.
A valid arrangement is a placement of all k pieces on the grid with at most one piece per cell.
Since the answer may be very large, return it modulo10^9 + 7.
The Manhattan Distance between two cells (xi, yi) and (xj, yj) is |xi -xj| + |yi - yj|.
Input: m =2, n =2, k =2Output: 8Explanation:
The valid arrangements of pieces on the board are:* In the first 4 arrangements, the Manhattan distance between the two pieces is1.* In the last 2 arrangements, the Manhattan distance between the two pieces is2.Thus, the total Manhattan distance across all valid arrangements is`1 + 1 + 1
+ 1 + 2 + 2 = 8`.
Input: m =1, n =4, k =3Output: 20Explanation:
The valid arrangements of pieces on the board are:
* The first and last arrangements have a total Manhattan distance of `1 + 1 + 2 = 4`.* The middle two arrangements have a total Manhattan distance of `1 + 2 + 3 = 6`.The total Manhattan distance between all pairs of pieces across all
arrangements is`4 + 6 + 6 + 4 = 20`.
The sum of Manhattan distances over all valid arrangements can be computed by considering all pairs of cells and counting how many arrangements place two pieces at those cells and the rest elsewhere. The number of such arrangements is C(m*n-2, k-2). We sum the Manhattan distance for each pair, multiplied by the number of ways to choose the remaining pieces.
constint MOD =1e9+7;
longlongmodpow(longlong a, longlong b, longlong mod) {
longlong res =1;
while (b) {
if (b &1) res = res * a % mod;
a = a * a % mod;
b >>=1;
}
return res;
}
vector<longlong> fact, invfact;
voidinit(int n) {
fact.resize(n+1, 1);
invfact.resize(n+1, 1);
for (int i =1; i <= n; ++i) fact[i] = fact[i-1] * i % MOD;
invfact[n] = modpow(fact[n], MOD-2, MOD);
for (int i = n-1; i >=0; --i) invfact[i] = invfact[i+1] * (i+1) % MOD;
}
longlongC(int n, int k) {
if (k <0|| k > n) return0;
return fact[n] * invfact[k] % MOD * invfact[n-k] % MOD;
}
classSolution {
public:int sumDistance(int m, int n, int k) {
int N = m * n;
init(N);
longlong ans =0;
// Row contribution
for (int i =0; i < m; ++i) {
for (int j = i+1; j < m; ++j) {
longlong cnt = n * n * (j - i);
ans = (ans + cnt * C(N-2, k-2)) % MOD;
}
}
// Col contribution
for (int i =0; i < n; ++i) {
for (int j = i+1; j < n; ++j) {
longlong cnt = m * m * (j - i);
ans = (ans + cnt * C(N-2, k-2)) % MOD;
}
}
return ans;
}
};
classSolution {
staticfinalint MOD = 1_000_000_007;
long[] fact, invfact;
voidinit(int n) {
fact =newlong[n+1];
invfact =newlong[n+1];
fact[0]= 1;
for (int i = 1; i <= n; i++) fact[i]= fact[i-1]* i % MOD;
invfact[n]= pow(fact[n], MOD-2);
for (int i = n-1; i >= 0; i--) invfact[i]= invfact[i+1]* (i+1) % MOD;
}
longpow(long a, long b) {
long res = 1;
while (b > 0) {
if ((b & 1) == 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
longC(int n, int k) {
if (k < 0 || k > n) return 0;
return fact[n]* invfact[k]% MOD * invfact[n-k]% MOD;
}
publicintsumDistance(int m, int n, int k) {
int N = m * n;
init(N);
long ans = 0;
for (int i = 0; i < m; i++) {
for (int j = i+1; j < m; j++) {
long cnt = 1L * n * n * (j - i);
ans = (ans + cnt * C(N-2, k-2)) % MOD;
}
}
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
long cnt = 1L * m * m * (j - i);
ans = (ans + cnt * C(N-2, k-2)) % MOD;
}
}
return (int)ans;
}
}
classSolution {
privateval MOD = 1_000_000_007L
privatelateinitvar fact: LongArray
privatelateinitvar invfact: LongArray
privatefunpow(a: Long, b: Long): Long {
var res = 1Lvar aa = a
var bb = b
while (bb > 0) {
if (bb and 1L==1L) res = res * aa % MOD
aa = aa * aa % MOD
bb = bb shr 1 }
return res
}
privatefuninit(n: Int) {
fact = LongArray(n+1) { 1L }
invfact = LongArray(n+1) { 1L }
for (i in1..n) fact[i] = fact[i-1] * i % MOD
invfact[n] = pow(fact[n], MOD-2)
for (i in n-1 downTo 0) invfact[i] = invfact[i+1] * (i+1) % MOD
}
privatefunC(n: Int, k: Int): Long {
if (k < 0|| k > n) return0Lreturn fact[n] * invfact[k] % MOD * invfact[n-k] % MOD
}
funsumDistance(m: Int, n: Int, k: Int): Int {
val N = m * n
init(N)
var ans = 0Lfor (i in0 until m) {
for (j in i+1 until m) {
val cnt = n.toLong() * n * (j - i)
ans = (ans + cnt % MOD * C(N-2, k-2) % MOD) % MOD
}
}
for (i in0 until n) {
for (j in i+1 until n) {
val cnt = m.toLong() * m * (j - i)
ans = (ans + cnt % MOD * C(N-2, k-2) % MOD) % MOD
}
}
return ans.toInt()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defsumDistance(self, m: int, n: int, k: int) -> int:
MOD =10**9+7from math import comb
N = m * n
if k <2:
return0 c = comb(N-2, k-2)
ans =0for i in range(m):
for j in range(i+1, m):
cnt = n * n * (j - i)
ans = (ans + cnt * c) % MOD
for i in range(n):
for j in range(i+1, n):
cnt = m * m * (j - i)
ans = (ans + cnt * c) % MOD
return ans
constMOD: i64=1_000_000_007;
fnmodpow(mut a: i64, mut b: i64, m: i64) -> i64 {
letmut res =1;
while b >0 {
if b &1==1 {
res = res * a % m;
}
a = a * a % m;
b >>=1;
}
res
}
fncomb(n: i64, k: i64, fact: &Vec<i64>, invfact: &Vec<i64>) -> i64 {
if k <0|| k > n { return0; }
fact[n asusize] * invfact[k asusize] %MOD* invfact[(n-k) asusize] %MOD}
impl Solution {
pubfnsum_distance(m: i32, n: i32, k: i32) -> i32 {
let N = (m * n) asi64;
letmut fact =vec![1; (N+1) asusize];
letmut invfact =vec![1; (N+1) asusize];
for i in1..=N asusize {
fact[i] = fact[i-1] * i asi64%MOD;
}
invfact[N asusize] = modpow(fact[N asusize], MOD-2, MOD);
for i in (0..N asusize).rev() {
invfact[i] = invfact[i+1] * (i asi64+1) %MOD;
}
let c = comb(N-2, k asi64-2, &fact, &invfact);
letmut ans =0i64;
for i in0..m {
for j in i+1..m {
let cnt = n asi64* n asi64* (j-i) asi64;
ans = (ans + cnt * c %MOD) %MOD;
}
}
for i in0..n {
for j in i+1..n {
let cnt = m asi64* m asi64* (j-i) asi64;
ans = (ans + cnt * c %MOD) %MOD;
}
}
ans asi32 }
}