所以我的问题是如何在C中更具体地做到这一点。我知道O(logn)通常意味着我们将以某种方式拆分其中一个参数来使用递归。
我想要达到的是x n 的k = 0到n的总和。 例如,exponent_sum(x,n)将是这种情况下的参数。
然后,
exponent_sum(4, 4)
将是4 0 + 4 1 + 4 2 + 4 3 + 4 4 = 341。
我不知道从哪里开始。一些提示将非常感激。
答案 0 :(得分:20)
查看总和的一种方法是基数x中包含全1的数字。
例如,4 4 + 4 3 + 4 2 + 4 1 + 4 0 在基数4中为11111。
在任何基数中,1s的字符串将等于1,后跟一个相同数字的0,减1的字符串除以基数减去1.
例如:
等
所以把这些放在一起,我们可以概括一下
exponent_sum(x,n)=(x (n + 1) - 1)/(x - 1)
例如,exponent_sum(4,4)=(4 5 - 1)/ 3 = 1023/3 = 341
因此,它的大O复杂度与计算x n
相同答案 1 :(得分:5)
让我为完整性添加另一个证据:
s = 1 + x 1 + x 2 + ... + x n
然后
xs = x(1 + x 1 + x 2 + ... + x n )= x 1 < / sup> + x 2 + ... + x n + x n + 1 = s - 1 + x n + 1
解决s
(x - 1)s = x n + 1 - 1,
s =(x n + 1 - 1)/(x - 1)
答案 2 :(得分:1)
查看解决方案的另一种方法是这样的:假设总和为S
,写为
S = 1 + x + x^2 + ... + x^k
然后,如果我们将它的两边乘以x
,我们得到
S*x = x * (1 + x + x^2 + ... + x^k)
= x + x^2 + ... + x^k + x^(k+1)
然后向双方添加1
S*x + 1 = 1 + x + x^2 + ... + x^k + x^(k+1)
= (1 + x + x^2 + ... + x^k) + x^(k+1)
= S + x^(k+1)
表示
S*x - S = x^(k+1) - 1
S*(x - 1) = x^(k+1) - 1
所以
S = (x^(k+1) - 1) / (x - 1)
答案 3 :(得分:1)
使用几何级数理论。其中
sum = (first-term(pow(common-ratio,number-of-terms)-1))/(common-ratio-1);
here first-term is obviously 1;
Common-ratio= number itself;
number-of-terms=number+1;
但普通比率应大于1; 对于
Common-ratio=1;
Sum=number*number-of-terms.
答案 4 :(得分:1)
您可以直接评估总和,而无需使用几何级数公式。这样做的优点是不需要除法(例如,如果你想调整代码以返回模数大的数字,那么这是必要的。)
让S(k)为和x ^ 0 + ... + x ^ {k-1},它满足这些递归关系:
S(1) = 1
S(2n) = S(n) * (1 + x^n)
S(2n+1) = S(n) * (1 + x^n) + x^{2n}
使用这些,唯一的困难是安排将xp
的运行值保持为x ^ n。否则,该算法非常类似于通过平方的自下而上的求幂实现。
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
int64_t exponent_sum(int64_t x, int64_t k) {
int64_t r = 0, xp = 1;
for (int i = 63; i >= 0; i--) {
r *= 1 + xp;
xp *= xp;
if (((k + 1) >> i) & 1) {
r += xp;
xp *= x;
}
}
return r;
}
int main(int argc, char *argv[]) {
for (int k = 0; k < 10; k++) {
printf("4^0 + 4^1 + ... + 4^%d = %" PRId64 "\n", k, exponent_sum(4, k));
}
return 0;
}