【算法】矩阵快速幂
【题解】
根据f[n]=f[n-1]+f[n-2],可以构造递推矩阵:
$$egin{vmatrix}1 & 1\ 1 & 0end{vmatrix} imes egin{vmatrix}f_n \ f_{n-1} end{vmatrix}=egin{vmatrix}f_{n+1}\f_nend{vmatrix}\$$
写成幂形式:
$$egin{vmatrix}1 & 1\ 1 & 0end{vmatrix}^n imes egin{vmatrix}1 \ 0end{vmatrix}=egin{vmatrix}f_{n+1}\f_nend{vmatrix}$$
矩阵快速幂。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int n=2,MOD=10000; int a[n][n],b[n][n],t[n][n],m; void mul(int a[n][n],int b[n][n],int ans[n][n]) { for(int i=0;i<n;i++) for(int j=0;j<n;j++) { t[i][j]=0; for(int k=0;k<n;k++) t[i][j]=(t[i][j]+a[i][k]*b[k][j])%MOD; } for(int i=0;i<n;i++) for(int j=0;j<n;j++) ans[i][j]=t[i][j]; } int main() { scanf("%d",&m); while(m!=-1) { if(m==0){printf("0 ");scanf("%d",&m);continue;} m--; a[0][0]=a[0][1]=a[1][0]=1;a[1][1]=0; b[0][0]=1;b[1][0]=b[0][1]=b[1][1]=0; while(m>0) { if(m&1)mul(a,b,b); m>>=1; mul(a,a,a); } printf("%d ",b[0][0]); scanf("%d",&m); } return 0; }
可以发现|1 0|乘上之后没有任何变化,所以可以得到更好看的式子:
$$egin{vmatrix}1 & 1\ 1 & 0end{vmatrix}^n=egin{vmatrix}f_{n+1} & f_n\ f_n & f_{n-1}end{vmatrix}$$
用来推性质十分方便,适用于n∈Z(可以是负数)。