DeepSeek LeetCode 3725. 统计每一行选择互质整数的方案数 Python3实现
以下是 LeetCode 3725 的 Python3 实现,使用容斥原理 + DP,思路与 Java 版本一致:
```python
from typing import List
class Solution:
def countCoprime(self, mat: List[List[int]]) -> int:
MOD = 10**9 + 7
MAX_VAL = 150
# 1. 预处理每个数的所有因子
divisors = [[] for _ in range(MAX_VAL + 1)]
for d in range(1, MAX_VAL + 1):
for multiple in range(d, MAX_VAL + 1, d):
divisors[multiple].append(d)
m = len(mat)
# 2. 统计每行中,能被 d 整除的数字个数
row_divisor_cnt = [[0] * (MAX_VAL + 1) for _ in range(m)]
for i in range(m):
for x in mat[i]:
for d in divisors[x]:
row_divisor_cnt[i][d] += 1
# 3. 容斥:计算"gcd恰好为d"的方案数
exact_gcd = [0] * (MAX_VAL + 1)
for d in range(MAX_VAL, 0, -1):
ways = 1
for i in range(m):
ways = (ways * row_divisor_cnt[i][d]) % MOD
if ways == 0:
break
# 减去 gcd 是 d 的倍数的方案
for multiple in range(2 * d, MAX_VAL + 1, d):
ways = (ways - exact_gcd[multiple]) % MOD
exact_gcd[d] = ways
return exact_gcd[1] % MOD
```
核心思路说明
1. 正向计算:row_divisor_cnt[i][d] 表示第 i 行中能被 d 整除的数字个数。那么所有行都选 d 的倍数的方案数为 ∏ row_divisor_cnt[i][d]。
2. 容斥去重:
· ∏ row_divisor_cnt[i][d] 实际上统计的是 gcd 为 d、2d、3d... 的所有方案
· 从大到小遍历 d,用 ways 减去所有 exact_gcd[multiple](multiple 是 d 的倍数),剩下的就是 gcd 恰好为 d 的方案数
3. 为什么从大到小:因为计算 exact_gcd[d] 需要用到 exact_gcd[2d]、exact_gcd[3d] 等更大的数,所以必须逆序计算。
复杂度分析
· 时间复杂度:O(m * n * τ + V²),其中 V=150,τ 是每个数的因子个数(≤12)
· 空间复杂度:O(m * V)
更多推荐





所有评论(0)