题目描述
小蓝有一个长度为 n 的数组 A = (a1, a2, · · · , an),数组的子数组被定义为从原数组中选出连续的一个或多个元素组成的数组。数组的最大公约数指的是数组中所有元素的最大公约数。如果最多更改数组中的一个元素之后,数组的最大公约数为 g,那么称 g 为这个数组的近似 GCD。一个数组的近似 GCD 可能有多种取值。
具体的,判断 g 是否为一个子数组的近似 GCD 如下:
- 如果这个子数组的最大公约数就是 g,那么说明 g 是其近似 GCD。
- 在修改这个子数组中的一个元素之后(可以改成想要的任何值),子数组的最大公约数为 g,那么说明 g 是这个子数组的近似 GCD。
小蓝想知道,数组 A 有多少个长度大于等于 2 的子数组满足近似 GCD 的值为 g。
传送门
解法
import math
n, g = map(int, input().split())
lst = [0] + list(map(int, input().split()))
right = 0 # 上一个不满足条件的元素的位置
left = 1
res = 0
for i in range(1, len(lst)):
t = math.gcd(g, lst[i]) # 求两个数的最大公因数
if t != g:
left = right + 1
right = i
if (i - left) + 1 >= 2:
res += i - left
print(res)
思路
双指针法,每个子数组中至多只能有一个不满足条件的元素
结果
正确
查漏补缺
求两个数的最大公因数:
可以使用python标准库math库中的gcd函数来实现。gcd函数实质上是通过辗转相除法实现的。
def gcd(a, b):
if a < b:
a, b = b, a
while b:
a, b = b, a % b
return a
更新日期
2024.02.23