zoukankan      html  css  js  c++  java
  • 【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(可以是负数)。

  • 相关阅读:
    动态规划-石子问题
    动态规划-最长不下降子序列
    STL 二分查找
    动态规划-最长公共子序列与最长公共子串
    动态规划-背包问题
    高精度运算模板学习
    二叉树 | 根据前序、后序生成中序
    03.动画
    02.绘制函数
    01.hello world
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6525931.html
Copyright © 2011-2022 走看看