The last time we learned how to calculate F (n) in log (n) time using the Fibonacci constant equation. This method is also suitable for the calculation of linear homogeneous recurrence series with Constant Coefficients. Here we will summarize what we can think.
Example 1: extend the Euclid algorithm.
The maximum public factor of two integers A and B is gcd (A, B ). The extended Euclid algorithm calculates the coefficient S and T in gcd (a, B) = SA + Tb while calculating gcd (A, B. Because:
In this way, as long as the product of the matrix in the middle is calculated, it is easy to calculate the coefficients S and T. The difference lies in connecting (A, B) and (B, R1) through a matrix.
Example 2: Number of Fibonacci instances.
F (n) = f (n-1) + f (n-2), which is a second-order recursive formula. Therefore, there is a second-order matrix. Like the above method, associate F (N), F (n-1) and F (n-1), F (n-2) through a matrix:
To calculate the power of N, you can use the rapid modulo algorithm to complete the process in log (n. The time used for a second-order matrix multiplication is a constant. Therefore, F (n) can be calculated within the complexity of log (n ).
You can also combine the number of Fibonacci on both sides of the equal sign to form a 2*2 matrix. That is:
The formula at the end shows that F (n + 1) and F (n) are mutually unique.
The common feature of the above two algorithms is to establish a recursive relationship through a matrix. The solution of linear recursive relationships with Constant Coefficients is always exponential. You can use this method to calculate the value of a specified item in the logarithm time complexity.
The following code is used to calculate the number of Fibonacci for a specified item and another recursive relationship a (K) = a (k-1) + a (K-2) + a (K-3), A (0) = 1, A (1) = a (2) = 2. The code is written in C ++, which is relatively lengthy. Remember this first.
// Quickly calculate the nth Number of Fiber-accids using a matrix equality <br/> # include <iostream> <br/> # include <cstring> <br/> # include <cstddef> <br/> # include <cassert> <br/> using namespace STD; </P> <p> template <typename T, size_t D> class Matrix {<br/> T data [d] [d]; <br/> static size_t CNT; <br/> Public: <br/> static matrix <t, D> identity; <br/> Public: <br/> matrix () {<br/> memset (data, 0, sizeof (data); <br/> If (CNT = 0) {<br/> memset (ID Entity. data, 0, sizeof (identity. data); <br/> for (INT I = 0; I <D; I ++) <br/> identity. data [I] [I] = 1; <br/>}< br/> CNT ++; <br/>}< br/> matrix (const T * arr, size_t N) {<br/> memset (data, 0, sizeof (data); <br/> size_t K = 0, r = 0, c = 0; <br/> while (k <n & R <D) {<br/> data [r] [C ++] = arr [k ++]; <br/> If (C = d) {<br/> r ++; C = 0; <br/>}< br/> If (CNT = 0) {<br/> memset (identity. Data, 0, sizeof (identity. data); <br/> for (INT I = 0; I <D; I ++) <br/> identity. data [I] [I] = 1; <br/>}< br/> CNT ++; <br/>}< br/> matrix (const Matrix & M) {<br/> memcpy (data, M. data, sizeof (data); <br/>}< br/> ~ Matrix () {CNT -- ;}</P> <p> Matrix & operator = (const Matrix & M) {<br/> If (this! = & M) {<br/> memcpy (data, M. data, sizeof (data); <br/>}< br/> return * This; <br/>}< br/> Matrix Operator * (const Matrix & M) {<br/> matrix result; <br/> for (size_t I = 0; I <D; I ++) {<br/> for (size_t J = 0; j <D; j ++) {<br/> result. data [I] [J] = 0; <br/> for (size_t K = 0; k <D; k ++) {<br/> result. data [I] [J] + = data [I] [k] * m. data [k] [J]; <br/>}< br/> return result; <br/>}< br/> Matrix & operator * = (const Matrix & M) {<br/> return (* This = * This * m ); <br/>}< br/> T * const operator [] (INT index) {<br/> assert (index> = 0 & index <D ); <br/> return data [Index]; <br/>}< br/> matrix power (size_t N) {<br/> matrix result = identity, TMP = * this; <br/> // while (n) {<br/> // If (N & 1) {<br/> // result * = TMP; <br/> // n --; <br/> //} else {<br/> // TMP * = TMP; <br/> // n/= 2; <br/> //} <br/> for (; n >>= 1) {<br/> If (N & 1) <br/> result * = TMP; <br/> TMP * = TMP; <br/>}< br/> return result; <br/>}</P> <p> friend istream & operator> (istream & in, matrix <t, D> & M) {<br/> for (size_t I = 0; I <D; I ++) <br/> for (size_t J = 0; j <D; j ++) <br/> in> M. data [I] [J]; <br/> return in; <br/>}< br/> friend ostream & operator <(ostream & out, const matrix <t, d> & M) {<br/> out. SETF (IOs: Left, IOS: adjustfield); <br/> for (size_t I = 0; I <D; I ++) {<br/> for (size_t J = 0; j <D; j ++) {<br/> out. width (4); <br/> out <m. data [I] [J]; <br/>}< br/> out <Endl; <br/>}< br/> return out; <br/>}< br/>}; </P> <p> template <typename T, size_t D> matrix <t, D> matrix <t, D> :: identity; <br/> template <typename T, size_t D> size_t matrix <t, d >:: CNT = 0; </P> <p> int main () {<br/> matrix <int, 2> fib; <br/> int N; </P> <p> fib [0] [0] = 1; <br/> fib [0] [1] = 1; <br/> fib [1] [0] = 1; <br/> fib [1] [1] = 0; <br/> CIN> N; </P> <p> int f [30] = {0, 1}; <br/> for (INT I = 2; I <30; I ++) <br/> F [I] = f [I-1] + F [I-2]; <br/> cout <"f [" <n <"] is: "<F [N] <Endl; </P> <p> cout <" f ["<n <"] = "<fib. power (n-1) [0] [0] <Endl; </P> <p> // A (K) = a (k-1) + a (K-2) + a (K-3), A (0) = 1, A (1) = 2, A (2) = 2 <br/> int am [] =, 0, 0, 0 }; <br/> matrix <int, 3> am (AM, sizeof (AM); <br/> CIN> N; <br/> matrix <int, 3> ret = aM. power (n-2 ); <br/> cout <"A [" <n <"] =" <RET [0] [0] * 2 + RET [0] [1] * 2 + RET [0] [2] <Endl; </P> <p> int A [30] = {1, 2, 2}; <br/> for (INT I = 3; I <30; I ++) <br/> A [I] = A [I-1] + A [I-2] + A [I-3]; <br/> cout <"A [" <n <"] is:" <A [n] <Endl; <br/> return 0; <br/>}< br/>