找到所有商的总和

时间:2013-03-09 07:21:50

标签: algorithm math

给出两个数字M和N.令qi是i * N / M的整数部分。从0到M-1,qi的总和是多少。 O(M)是显而易见的方法。这可以在更短的时间内完成,如果存在一些更简单的简化表达式,可能是O(1)吗?

2 个答案:

答案 0 :(得分:3)

有趣的问题。 (这篇文章会让我希望我们在SO上有数学格式......)

我的方法是将问题写成

∑i floor(i*N/M) = ∑i i*N/M - ∑i [i*N/M]

其中[]是“小数部分”运算符(即[1.3] = 0.3,[6] = 0等)。

然后,前半部分很简单:它是一个正常的算术序列和乘以N/M,因此它总和为N*(M-1)/2。下半场比较棘手,但是你会明白为什么将它与上半场分开是至关重要的。

k = gcd(N, M)。然后,让n = N/km = M/k,让后半部分为∑i [i*n/m]。至关重要的是,nm现在相对来说是素数。 i的总和从0M-1 = km-1。我们可以将i拆分为m的倍数,将剩余部分拆分为i = qm + r,以便总和现在

∑q ∑r [r*n/m]

其中q总和从0k-1r总和从0m-1。现在是关键步骤:因为nm是相对素数,r*n的序列r = 0..m-10, 1, 2, 3, ..., m-1的{​​em>置换 } mod m 。因此,序列[r*n/m]0/m, 1/m, 2/m, ..., (m-1)/m排列,因此∑r [r*n/m] = ∑r r/m = m*(m-1)/2/m = (m-1)/2。因此,整个总和折叠为k * (m-1)/2 = (km - k) / 2 = (M - k) / 2

最后,我们将两半结合起来:N*(M-1)/2 - (M-k)/2 = (NM - N - M + k)/2

因此,期望的总和是(NM - N - M + gcd(N, M))/2。使用Euclid算法可以relatively quickly计算GCD,因此计算速度相当快。

答案 1 :(得分:0)

在我看来,你试图将0N / M + 1N / M + 2N / M + 3N / M ......(M-1)N / M加起来。如果是这样,你有(0 + 1 + 2 + 3 ... +(M-1))N / M.您可以在O(1)中解决这个问题,因为(0 + 1 + 2 + 3 + ... +(M-1))是M *(M-1)/ 2。 M取消,你得到(M-1)N / 2.