质数相关
leecode1201,丑数,容斥定理+二分+最小公倍数
import math class Solution: def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int: ab = math.lcm(a,b) bc = math.lcm(b,c) ac = math.lcm(a,c) abc = math.lcm(a,b,c) def check(num): cnt = 0 cnt += num//a cnt += num//b cnt += num//c cnt -= num//ab cnt -= num//bc cnt -= num//ac cnt += num//abc return cnt>=n low = 1 high = 2*10**9+1 ans = 0 while low < high: mid = (low+high)//2 if check(mid): high = mid ans = mid else: low = mid +1 return ans
gcd,lcm,注意两个数和三个数的求法。
def gcd(a,b): a,b = (a,b) if a>=b else (b,a) while b!= 0: a,b = b,a%b return a def gcd(a,b): a,b = (a,b) if a>=b else (b,a) if a%b == 0: return b else: return gcd(b,a%b) def lcm(a,b): return a*b//gcd(a,b) # a = 6 # b = 9 # print(gcd(a,b),lcm(a,b)) # 求三个数的最大公因数和最小公倍数 a = 6 b = 9 c = 12 print(gcd(a,gcd(b,c))) print(lcm(a,lcm(b,c))) print(a*lcm(b,c)/gcd(a,lcm(b,c)))
leecode2470,最小公倍数为k的子数组,动态规划(可优化空间),lcm性质:连续数组的lcm最可能增大。
时间复杂度见力扣
import math class Solution: def subarrayLCM(self, nums: List[int], k: int) -> int: n = len(nums) ans = 0 for i in range(n): dp = nums[i] for j in range(i,n): dp = math.lcm(dp,nums[j]) if dp == k: ans += 1 elif dp>k: break return ans