矩阵快速幂求斐波那契
基本形式

用矩阵分析
由上式分析可得:求F(n)等于求二阶矩阵的n - 1次方,结果取矩阵第一行第一列的元素。
快速幂优化
二阶矩阵的乘法满足结合律
设A,B,C都是任意的二阶矩阵
A(BC)=(AB)C
设n=N/2 结果向下取整
相当于
由上式可得:通过快速幂来减少运算次数
代码
矩阵(结构体构造)
1 2 3 4
| struct node { LL a[2][2]; };
|
矩阵乘法
1 2 3 4 5 6 7 8 9 10
| node mul(node x,node y) { node z; memset(z.a,0,sizeof(z.a)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%mod; return z; }
|
求斐波那契第n个数
1 2 3 4 5 6 7 8 9 10 11 12 13
| void quick(LL n) { node c,res; c.a[0][0]=1,c.a[0][1]=1,c.a[1][0]=1,c.a[1][1]=0; res.a[0][0]=1,res.a[0][1]=0,res.a[1][0]=0,res.a[1][1]=1; while(n){ if(n&1)res=mul(res,c); c=mul(c,c); n=n>>1; } cout<<res.a[0][1]<<endl; }
|
即所求res矩阵中的a[0][1]
全部代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include<bits/stdc++.h> using namespace std; typedef long long LL; const double pi=acos(-1),eps=1e-10; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int m=10007;
struct node { LL a[2][2]; }; LL n,sum;
node mul(node x,node y) { node z; memset(z.a,0,sizeof(z.a)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%mod; return z; }
void quick(LL n) { node c,res; c.a[0][0]=1,c.a[0][1]=1,c.a[1][0]=1,c.a[1][1]=0; res.a[0][0]=1,res.a[0][1]=0,res.a[1][0]=0,res.a[1][1]=1; while(n){ if(n&1)res=mul(res,c); c=mul(c,c); n=n>>1; } cout<<res.a[0][1]<<endl; }
int main() { cin>>n; quick(n);
return 0; }
|
斐波那契数列前n项求和
斐波那契数列前n项平方求和
用几何证明

分析
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include<bits/stdc++.h> using namespace std; typedef long long LL; const double pi=acos(-1),eps=1e-10; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int m=10007;
struct node { LL a[2][2]; }; LL n,sum;
node mul(node x,node y) { node z; memset(z.a,0,sizeof(z.a)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%mod; return z; }
void quick(LL n) { node c,res; c.a[0][0]=1,c.a[0][1]=1,c.a[1][0]=1,c.a[1][1]=0; res.a[0][0]=1,res.a[0][1]=0,res.a[1][0]=0,res.a[1][1]=1; while(n){ if(n&1)res=mul(res,c); c=mul(c,c); n=n>>1; } cout<<(res.a[0][0]%mod*res.a[0][1]%mod)%mod<<endl; }
int main() { cin>>n; quick(n);
return 0; }
|
即res矩阵的a[0][0]与a[0][1]相乘(注意取模)