普通的斐波那契数列的递推式很简单,但是如果要求第1014个斐波那契数的话,肯定会tle,这时就可以用矩阵快速幂来优化。
菲波那切数列普通的递推式是
f[i]=f[i-1]+f[i-2]
而矩阵乘法的规则是,讲n行m列的矩阵与k行n列的矩阵相乘,所得矩阵的第i行第j列的数是由第一个矩阵的第i列的每个数与第二个矩阵的第j行的每个数分别相乘,然后相加所得。
然后我们考虑上面的递推式,可以看做是
f[i]=f[i-1]*1+f[i-2]*1 f[i-1]=f[i-1]*1+f[i-2]*0
讲这些都看作是矩阵的话,那么
然后求第n个斐波那契数就是求
然后利用矩阵快速幂就可以了
例题codevs1732
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll; 6 const ll mod=1000000007; 7 struct node 8 { 9 ll a[5][5]; 10 }aa; 11 node mul(node &x,node &y) 12 { 13 node c; 14 for(int i=1;i<=2;++i) 15 for(int j=1;j<=2;++j) 16 { 17 c.a[i][j]=0; 18 for(int k=1;k<=2;++k) 19 c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod; 20 } 21 return c; 22 } 23 void quick(ll n) 24 { 25 node c; 26 aa.a[1][1]=aa.a[2][1]=aa.a[1][2]=1,aa.a[2][2]=0; 27 c.a[1][1]=c.a[2][1]=1; 28 c.a[1][2]=c.a[2][2]=0; 29 while(n) 30 { 31 if(n&1) 32 c=mul(c,aa); 33 n>>=1; 34 aa=mul(aa,aa); 35 } 36 //printf("%d %d\n%d %d\n",aa.a[1][1],aa.a[1][2],aa.a[2][1],aa.a[2][2]); 37 cout<<c.a[1][1]<<"\n"; 38 return; 39 } 40 int main() 41 { 42 ll n; 43 while(cin>>n) 44 quick(n-1); 45 return 0; 46 }