📅  最后修改于: 2023-12-03 15:36:57.914000             🧑  作者: Mango
给定正整数 $N$ 和 $K$,求前 $N$ 个自然数之和,且该和不是 $K$ 的幂。
我们可以直接对前 $N$ 个自然数进行求和,判断该和是否为 $K$ 的幂。如果是,则继续求和,直到求出一个不是 $K$ 的幂的和为止。
为了避免重复计算,我们可以利用数学公式求出前 $N$ 个自然数之和,即等差数列求和公式:$1+2+\cdots+N=\frac{N(N+1)}{2}$。利用该公式可以使时间复杂度降低。
同时,我们可以利用快速幂算法判断某个数是否是 $K$ 的幂,从而避免使用循环求幂,将时间复杂度更进一步降低。
def sum_without_k_power(N: int, K: int) -> int:
# 计算前N个自然数之和
total_sum = N * (N + 1) // 2
# 判断总和是否是K的幂
while K > 1:
if total_sum % K == 0:
total_sum += N + 1
N += 1
else:
break
# 利用快速幂判断是否是幂
def fast_pow(base, exp):
res = 1
while exp:
if exp & 1:
res *= base
base *= base
exp >>= 1
return res
if K == 1 or fast_pow(K, int(round(math.log(total_sum, K)))) != total_sum:
return total_sum
else:
return sum_without_k_power(N + 1, K)
该函数的时间复杂度为 $O(\log K\log N)$,空间复杂度为 $O(1)$,可用于较大的输入。