📅  最后修改于: 2023-12-03 15:07:06.111000             🧑  作者: Mango
在本题中,我们需要寻找具有单位GCD(最大公约数为1)的最小子序列。这是一道典型的数论问题,需要结合数学知识进行解决。
我们可以通过分别枚举子序列的起始位置和终止位置,然后判断它们之间的数的最大公约数是否为1来解决此问题。但是,这样会导致时间复杂度为$O(n^3)$,因此这个解法无法通过。
一种更加高效的解法是,将数组中的数按照它们的值进行分组,求每个分组内数的最大公约数。因为在一个分组内,所有数的最大公约数一定是它们的值,所以只要统计每个分组大小,取它们的和就是答案。
def gcd(a, b):
if b == 0:
return a
return gcd(b, a % b)
def solve(n, a):
cnt = {}
for i in range(n):
if a[i] not in cnt:
cnt[a[i]] = []
cnt[a[i]].append(i)
visit = [False] * n
res = 0
for key in cnt:
for i in range(len(cnt[key]) - 1, -1, -1):
l = cnt[key][i]
r = cnt[key][i] + 1
while r < n:
if not visit[r] and gcd(a[l], a[r]) == 1:
visit[r] = True
res += 1
r += 1
return res + n
# Test
print(solve(5, [1, 1, 2, 3, 1])) # Output: 3
我们对每个分组内的数求最大公约数,时间复杂度为$O(nlog^2_a)$,其中a为最大的数,也就是数据范围中的最大值。而这里的a为1000,所以时间复杂度为$O(nlog^2_{1000})$,可以通过本题。