【POJ】3070 Fibonacci

【算法】矩阵快速幂

【题解】

根据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;
}
View Code

可以发现|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(可以是负数)。

原文地址:https://www.cnblogs.com/onioncyc/p/6525931.html