📜  前N个自然数之和,不是K的幂(1)

📅  最后修改于: 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)$,可用于较大的输入。