【POJ】3070 Fibonacci

【算法】矩阵快速幂

【题解】

根据f[n]=f[n-1]+f[n-2],可以构造递推矩阵:

$$\begin{vmatrix}1 & 1\\ 1 & 0\end{vmatrix} \times \begin{vmatrix}f_n \\ f_{n-1} \end{vmatrix}=\begin{vmatrix}f_{n+1}\\f_n\end{vmatrix}\\$$

写成幂形式:

$$\begin{vmatrix}1 & 1\\ 1 & 0\end{vmatrix}^n \times \begin{vmatrix}1 \\ 0\end{vmatrix}=\begin{vmatrix}f_{n+1}\\f_n\end{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\n");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\n",b[0][0]);
         scanf("%d",&m);
     }
    return 0;
}
View Code

 

可以发现|1 0|乘上之后没有任何变化,所以可以得到更好看的式子:

$$\begin{vmatrix}1 & 1\\ 1 & 0\end{vmatrix}^n=\begin{vmatrix}f_{n+1} & f_n\\ f_n & f_{n-1}\end{vmatrix}$$

用来推性质十分方便,适用于n∈Z(可以是负数)。

posted @ 2017-03-09 15:31  ONION_CYC  阅读(177)  评论(0编辑  收藏  举报