📅  最后修改于: 2023-12-03 15:42:18.613000             🧑  作者: Mango
给定 $n$ 个整数的列表 $A$,每个整数均大于 $0$。定义两个整数 $x$ 和 $y$ 的给分为 $gcd(x,y)$ ($x$ 和 $y$ 的最大公因数)。考虑 $n$ 个整数的量表对于任何给定的对 $(i,j)$,$i < j$,返回 $A_i$ 和 $A_j$ 的得分的和。 如果你求出 $O(n^2)$ 时间复杂度的算法,那么你将不会通过此题。该算法的时间复杂度应该为 $O(nlogn)$。
以下为样例输入输出:
A = [1, 2, 3, 4, 5]
31
这道题目需要我们求出 $A_i$ 和 $A_j$ 的得分的和,即 $gcd(A_i,A_j)$。而 $gcd$ 函数实际上是 $O((logn)^2)$ 的复杂度,因此 $O(n^2)$ 显然是不可行的。 但是,如果我们将其分解质因数,将时间复杂度降为 $O(nlognlogA_ilogA_j)$,那么我们可以顺利AC这个问题。
具体实现,我们可以首先求出所有数的质因数分解。然后对于给定的 $i,j$,我们可以对其进行遍历,对于某个数列 $k$,计算 $k$ 中质因子中同时含有 $A_i$ 和 $A_j$ 的数量,求和即可。
代码如下:
from typing import List
import math
def gcd(a: int, b: int) -> int:
if b == 0:
return a
return gcd(b, a % b)
def primeFactorization(num: int) -> List[int]:
result = []
while num % 2 == 0:
result.append(2)
num //= 2
for i in range(3, int(math.sqrt(num))+1, 2):
while num % i == 0:
result.append(i)
num //= i
if num > 2:
result.append(num)
return result
def sum_world_metric(A: List[int]) -> int:
n = len(A)
world_metric = [[0] * n for _ in range(n)]
for i in range(n):
factor_i = primeFactorization(A[i])
for j in range(i+1, n):
factor_j = primeFactorization(A[j])
world_metric[i][j] = sum(1 for x in factor_i if x in factor_j)
world_metric[j][i] = world_metric[i][j]
result = 0
for i in range(n):
for j in range(i+1, n):
result += gcd(A[i], A[j]) * world_metric[i][j]
return result
代码中 primeFactorization
函数用于质因数分解,world_metric
存储了任意两个 $A_i$ 和 $A_j$ 在质因子中同时含有的数量,最后遍历计算即可。
时间复杂度为 $O(nlognlogA_ilogA_j)$,可以通过本题。