SubArray Fibonacci数的和

时间:2016-10-30 09:48:49

标签: algorithm math fibonacci

我有一个N个数字的数组A.我必须找到所有子阵列之和的斐波纳契数的总和。 例如:

A = {1,1}
F[Sum A[1,1]] = F[1] = 1
F[Sum A[1,2]] = F[2] = 1
F[Sum A[2,2]] = F[1] = 1
Ans = 1 + 1 + 1 = 3

问题类似于this,但我需要计算标准Fibonacci序列的总和。 这是source code

这里使用了什么属性?
任何人都能解释这背后的数学吗?如何避免O(N^2)解决方案?如何修改标准Fibonacci数的源代码?

1 个答案:

答案 0 :(得分:0)

这是一个在O(N * log MAX_A * k^3)时间内运行的解决方案(其中MAX_A是数组中的最大值,k是递归公式中使用的变量数(等于2对于斐波纳契和3对于你的问题链接的问题。)我不会参考你提供的源代码,因为它很难阅读,但看起来它使用类似的想法:

  1. 让我们快速了解如何计算i-th斐波纳契数。很容易看出f(i) = F^n * [1, 1].transposed(),其中F是一个矩阵[[1, 1], [1, 0]](对于原始问题,它将是[[1, 1, 1], [1, 0, 0], [0, 0, 1]]。我们可以找到{{1}使用二进制求幂快速矩阵的幂。

  2. 让我们进一步发展这个想法。就矩阵而言,我们要求评估以下表达式:

    n-th

    或等效地(因为矩阵乘法对于加法是分布式的)

    sum for all valid L, R of ((F^(a[L] + ... + a[R]) * [1, 1].transposed())[0])
    
  3. 现在我们需要弄清楚如何有效地计算这个总和。让我们学会逐步进行。让我们假设已经处理了位于((sum for all valid L, R of F^(a[L] + ... + a[R])) * [1, 1].transposed())[0] 或更小位置的所有子数组,并且我们想要添加下一个。根据问题陈述,我们应该在答案中添加n,这等于F^a[n + 1] + F^(a[n + 1] + a[n]) + ... + F^(a[n + 1] + a[n] + ... + a[0])

  4. 那就是它。我们已经有了有效的解决方案。这里有一个伪代码:

    F^a[n + 1] * (F^a[n] + F^(a[n] + a[n - 1]) + ... + F^(a[n] + a[n - 1] + ... + a[0]))
  5. 假设矩阵pref_sum = I // identity matrix. This variable holds the second // term of the product used in step 3 total_sum = zeros // zero matrix of an appropriate size // It holds the answer to the problem for i = 0 .. N - 1 cur_matrix = binary_exponentiation(F, a[i]) // A matrix for the a[i]-th fibonacci number // Everything is updated according to the formulas shown above total_sum += pref_sum * cur_matrix pref_sum = pref_sum * cur_matrix + I // Now we just need to mulitiply the total_sum by an appropriate vector // which is [1, 1].transposed() in case of Fibonacci numbers 的大小是常数(在Fibonacci数的情况下再次为2),时间复杂度为F,因为只有对原始数组的每个元素进行一次二进制求幂,然后进行恒定数量的矩阵乘法和加法。