📌  相关文章
📜  给定范围[L,R]中Array元素的倍数总和(1)

📅  最后修改于: 2023-12-03 15:11:40.625000             🧑  作者: Mango

给定范围[L,R]中Array元素的倍数总和

在编写程序时,经常需要给定一个范围[L,R],计算数组中满足一定条件的元素总和。其中,常见的一个问题是计算一个数组中所有元素的倍数的总和。以下是一个介绍如何解决这个问题的方法。

方法一:暴力枚举

最简单的方法是对数组中的每个元素进行检查,判断它是否可以被L到R之间的任意一个数整除,如果可以,则将其加入到结果中。下面是示例代码:

def multiple_sum(arr, L, R):
    ans = 0
    for x in arr:
        for i in range(L, R + 1):
            if i % x == 0:
                ans += i
    return ans

这种方法的时间复杂度为O($n\times(R-L)$),在数组和范围很大时会非常慢。

方法二:优化枚举

为了减少暴力枚举的时间,可以先计算出范围[L,R]内所有元素的倍数,然后再计算这些倍数在数组中出现的次数。下面是示例代码:

def multiple_sum(arr, L, R):
    ans = 0
    cnt = [0] * (R + 1)
    for x in arr:
        for i in range(x, R + 1, x):
            cnt[i] += 1
    for i in range(L, R + 1):
        ans += i * cnt[i]
    return ans

这种方法的时间复杂度为O($n\times\frac{R}{x}$),其中$x$为数组中最大的元素值。当$x$很大时,这种方法效率会更高。

方法三:数学运算

还可以运用数学的方法计算这个问题。根据等差数列求和公式,可以容易地得出[L,R]内所有的x的倍数的和为:

$$ans=\frac{(L+R)\times cnt}{2}\times x$$

其中,$cnt=\lfloor\frac{R}{x}\rfloor-\lceil\frac{L}{x}\rceil+1$表示x在[L,R]内出现的次数。下面是示例代码:

def multiple_sum(arr, L, R):
    ans = 0
    for x in arr:
        cnt = (R // x) - (L // x) + 1
        ans += (L + R) * cnt // 2 * x
    return ans

这种方法的时间复杂度为O($n$),是最快的一种方法。

在实际编程中,还可以根据具体问题的特点,结合以上方法进行优化和改进,以获得更好的效果。