📅  最后修改于: 2023-12-03 15:10:59.545000             🧑  作者: Mango
本题的目标是在给定的整数集(1 ≤ 𝐴[𝑖] ≤ 𝑁)中找到符合以下条件的连续子序列:
首先可以想到的是进行暴力枚举,即枚举每个可能符合条件的子序列,判断其第一个元素是否为质数,以及是否恰好具有𝐾个小于𝑁的质因子。但此方法时间复杂度为 $𝑂(𝑁^3)$,无法通过本题。
考虑优化暴力枚举方法,将每个可能符合条件的子序列的第一个元素的质因数分解出来,然后记录下每个质因数的出现次数和质因数的种类数。使用滑动窗口来移动子序列,每次移动的时候判断加入和移除的元素的质因数对答案有没有贡献即可。
时间复杂度为 $𝑂(𝐾𝑁log_2(𝑁))$,可以通过本题。具体实现可以参考下方代码。
def count_prime_factors(n, primes):
"""
计算n的质因数分解结果
"""
res = {}
for p in primes:
while n % p == 0:
if p not in res:
res[p] = 0
res[p] += 1
n //= p
if n == 1:
break
if n > 1:
if n not in res:
res[n] = 0
res[n] += 1
return res
def solve(N, K):
# 计算N以内的所有质数
primes = []
is_prime = [True] * (N + 1)
for i in range(2, N + 1):
if is_prime[i]:
primes.append(i)
for j in range(i * i, N + 1, i):
is_prime[j] = False
# 计算每个数的质因数分解结果
A = []
for i in range(1, N + 1):
A.append(count_prime_factors(i, primes))
# 滑动窗口求解
ans = 0
cnt = {}
j = 0
for i in range(N - K + 1):
while j < N and len(cnt) < K:
for p, c in A[j].items():
if p not in cnt:
cnt[p] = 0
cnt[p] += c
j += 1
if len(cnt) == K:
is_prime = True
for p in A[i]:
if cnt.get(p, 0) != A[i][p]:
is_prime = False
break
if is_prime:
ans += 1
for p, c in A[i].items():
if cnt[p] == c:
del cnt[p]
else:
cnt[p] -= c
return ans