The problem of solving Fibonacci sequence by matrix is a more common question in ACM problem. Example: Nyoj 148 (Fibonacci sequence 2).
See here for the rules of the Ponachi column.
(1), for n>1, there are f (n) and F (n-1) coprime.
(2), f (n) =f (i) *f (n-i-1) +f (i+1) *f (n-i).
Now let's talk about how to use matrices to solve Fibonacci sequences.
We can first save B=f (1), a=f (0), and then set: B ' =a+b a ' =b each time. After the use of a ' and B ' has been circulating. At the same time we can consider B a as a vector [B a], the preceding operation can be multiplied by the matrix:
|-1|*[b a]=[a+b b].
|-0|
In other words, if we ask for a 100th Fibonacci number, we simply multiply the matrix [1 0]
1 1
1 0
100 times, then take out the second item. As described in the topic: set F0 = 0,F1 = 1, then there are:
.
The N-square form of this matrix is:
F (n+1) f (n)
F (N) F (n-1),
The question now is how to find out how many n times this matrix is.
There are two methods that you can use:
(1), can take advantage of the idea of two points: assuming that the N-th square of The matrix is a (n), set I=N/2 if N%2==1, then a (n) =a (i) *a (i) *a (1) If n%2==0, then a (n) =a (i) *a (i).
(2), using the idea of binary: to split n into binary number, such as 13 = (1101) 2 then a^13= a^8 * a^4 * a^1. This is often used when seeking a fast power modulus. See the code, can do template, write the comparison of the chaos:
#include <iostream> #include <cstring> using namespace std;
const int max=10;
#define __int64 Long Long #define BIT (n) 1<<n #define CLR (arr,val) memset (arr,val,sizeof (arr)) class matrix{public:
Matrix (int r,int c): Row (R), col (c) {} void Init () {CLR (map,0);
Map[0][0]=map[0][1]=map[1][0]=1;
} void Unit ()//initialized to the unit matrix {CLR (map,0);
for (int i=0;i<row;i++) map[i][i]=1;
} int Result () Const{return map[0][1]%10000;}
Friend Matrix operator* (const matrix&, const matrix&);
int Pow (int);
Private: __int64 Map[max][max];
int row,col;
}; Matrix operator* (const matrix& m1,const matrix& M2)//matrix multiplication Template {matrix M (m1.row,m2.col);//multiply the rows and columns of matrices will change F
or (int i=0;i<m1.row;i++) for (int j=0;j<m2.col;j++) {m.map[i][j]=0;
for (int k=0;k<m1.col;k++) M.MAP[I][J]+=M1.MAP[I][K]*M2.MAP[K][J];
m.map[i][j]%=10000; } return M;
} Matrix M (2,2);
int matrix::P ow (int n)//matrix fast Power {Matrix temp (2,2); Temp.
Init (); for (int i=0;
Bit (i) <=n;i++)//using binary thinking to solve {if (Bit (i) &n) m=m*temp;
Temp=temp*temp;
} return M.result ();
} int main () {__int64 num;
while (cin>>num,num!=-1) {m.unit ();
Cout<<m.pow (num) <<endl;
} return 0; }
Here, by the way, put the formula for the Fibonacci sequence:
We can use this formula to simplify many operations: example HDU 2855, which means input n,m,%m results.
The specific derivation process is as follows:
The last topic asks F (n)%m value, this is the value of f (2n)%m, you understand ~ code is not much write ~
Debugging several times 10^9 this number is not enough, the matrix of the rapid power of the template changed over the ~ specifically changed to the following:
int matrix::P ow (int n)//matrix fast power
{ Matrix temp (2,2);
Temp. Init ();
while (n)//using binary thinking to solve
{ if (n&1) m=m*temp;
Temp=temp*temp;
n>>=1;
}
return M.result ();
}
Example 2:nyoj 507 (Fibonacci sequence), just write that recursive relationship can ~ the rest of the direct set of templates:
S (n) =f (0) 2+f (1) 2+f (2) 2+...+f (n) 2;
S (n-1) =f (0) 2+f (1) 2+f (2) 2+...+f (n-1) 2.
So: s (n)-S (n-1) =f (n) 2=x2f (n-1) 2+y2f (n-2) 2+2XYF (n-1) f (n-2).
So you can construct the following matrix:
This time is simple, specifically see the code:
#include <iostream> #include <cstring> #include <cstdio> using namespace std;
const int max=10;
#define __int64 Long Long #define CLR (arr,val) memset (arr,val,sizeof (arr)) int x,y,num;
Class matrix{Public:matrix (int r,int c): Row (R), col (c) {} void Init () {CLR (map,0);
x%=10007,y%=10007;//must add to this condition ~ ~ map[0][0]=map[0][1]=map[2][1]=1;
map[1][1]=x*x%10007;
map[1][2]=y*y%10007;
map[1][3]= (2*x*y)%10007;
map[3][1]=x%10007,map[3][3]=y%10007;
} void Unit ()//initialized to the unit matrix {CLR (map,0);
for (int i=0;i<row;i++) map[i][i]=1;
} void Clear () {for (int i=0;i<4;i++) map[i][0]=1;
} int Result () const {return map[0][0]%10007;}
Friend Matrix operator* (const matrix&, const matrix&);
Friend ostream& operator<< (ostream&, const matrix&);
int Pow (int);
Private: __int64 Map[max][max];
int row,col;
}; MatrIX operator* (const matrix& m1,const matrix& M2) {Matrix M (m1.row,m2.col);
for (int i=0;i<m1.row;i++) for (int j=0;j<m2.col;j++) {m.map[i][j]=0;
for (int k=0;k<m1.col;k++) M.MAP[I][J]+=M1.MAP[I][K]*M2.MAP[K][J];
m.map[i][j]%=10007;
} return M;
} Matrix M (bis);
int Matrix::P ow (int n) {Matrix temp (+), Start (4,1); Temp.
Init ();
Start.clear ();
cout<<temp;
while (n) {if (n&1) m=m*temp;
Temp=temp*temp;
n>>=1;
} Start=m*start;
return Start.result (); } ostream& operator<< (ostream &cout,const matrix& M) {for (int. i=0;i<m.row;i++) {for (int j=0
; j<m.col;j++) cout<<m.map[i][j]<< "";
cout<<endl;
} return cout;
} int main () {while (scanf ("%d%d%d", &num,&x,&y)!=eof) {m.unit ();
Cout<<m.pow (num) <<endl;
} return 0;
}