zoukankan      html  css  js  c++  java
  • 斐波那契数列第N项f(N)[矩阵快速幂]

    矩阵快速幂

    ---!x^n+y^n=z^n

      定义矩阵A(m*n),B(p*q),A*B有意义当且仅当n=p。即A的列数等于B的行数。

      且C=A*B,C(m*q)。

      例如:

      进入正题,由于现在全国卷高考不考矩阵,也没多大了解。因为遇到了斐波那契这题...

      注意到: Fn+1=Fn+Fn-1

      我们会有:

      则:

      所以我们只需要想办法求矩阵A的幂,这时候我们当然想要用快速幂。


    代码部分:

    定义矩阵:

    struct matrix{
        ll a[3][3];
    };

    (类比整数的快速幂)预处理:

    [我们需要一类似于1的矩阵:]

    『1 0 0

        0 1 0

        0 0 1』类似这种操作...

    void init(){
            int i,j;
            memset(res.a,0,sizeof res.a);
            for(i=1;i<=2;i++) res.a[i][i]=1;
            base.a[1][1]=1;
            base.a[1][2]=1;
            base.a[2][1]=1;
            base.a[2][2]=0;
    }

    矩阵乘法:[就该题而言]

    matrix mul(matrix p,matrix q){
            int i,j,k;
            matrix m;
            memset(m.a,0,sizeof m.a);
            for(i=1;i<=2;i++)
                for(j=1;j<=2;j++)
                    for(k=1;k<=2;k++)
                        m.a[i][j]=(m.a[i][j]+p.a[i][k]*q.a[k][j])%Mod;
            return m;
    }

    快速幂:

    void mfpow(ll p){
            init();
            while(p){
                if(p&1) res=mul(base,res);
                base=mul(base,base);
                p>>=1;
            } 
     }

    全部的代码:(lowbee的难免会差一些,请大佬们见谅...)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long ll ;
     6 inline ll read();
     7 const ll Mod = 1e9 + 7 ;
     8 struct matrix{
     9     ll a[3][3];
    10 };
    11 matrix res,base;
    12 ll ans;
    13 ll c[3];
    14 ll n;
    15 namespace lys{
    16     void init(){
    17         int i,j;
    18         memset(res.a,0,sizeof res.a);
    19         for(i=1;i<=2;i++) res.a[i][i]=1;
    20         base.a[1][1]=1;
    21         base.a[1][2]=1;
    22         base.a[2][1]=1;
    23         base.a[2][2]=0;
    24     }
    25     matrix mul(matrix p,matrix q){
    26         int i,j,k;
    27         matrix m;
    28         memset(m.a,0,sizeof m.a);
    29         for(i=1;i<=2;i++)
    30             for(j=1;j<=2;j++)
    31                 for(k=1;k<=2;k++)
    32                     m.a[i][j]=(m.a[i][j]+p.a[i][k]*q.a[k][j])%Mod;
    33         return m;
    34     }
    35     void mfpow(ll p){
    36         init();
    37         while(p){
    38             if(p&1) res=mul(base,res);
    39             base=mul(base,base);
    40             p>>=1;
    41         } 
    42     }
    43     int main(){
    44         int k;
    45         n=read();
    46         mfpow(n-1);
    47         c[1]=1;
    48         c[2]=0;
    49         for(k=1;k<=2;k++)
    50             ans=(ans+res.a[1][k]*c[k])%Mod;    
    51         cout<<ans<<endl;    
    52         return 0;    
    53     }
    54 }
    55 int main(){
    56     lys::main();
    57     return 0;
    58 }
    59 inline ll read(){
    60     ll k=0,f=1;
    61     char c=getchar();
    62     while(c<'0'||c>'9'){
    63         if(c=='-')
    64             f=-1;
    65         c=getchar();
    66     }
    67     while(c>='0'&&c<='9'){
    68         k=k*10+c-'0';
    69         c=getchar();
    70     }
    71     return k*f;
    72 }

    题目链接[luogu]:

    https://www.luogu.org/problem/show?pid=1962

  • 相关阅读:
    Python入门11 —— 基本数据类型的操作
    Win10安装7 —— 系统的优化
    Win10安装6 —— 系统的激活
    Win10安装5 —— 系统安装步骤
    Win10安装4 —— 通过BIOS进入PE
    Win10安装2 —— 版本的选择与下载
    Win10安装1 —— 引言与目录
    Win10安装3 —— U盘启动工具安装
    虚拟机 —— VMware Workstation15安装教程
    Python入门10 —— for循环
  • 原文地址:https://www.cnblogs.com/_inx/p/7631999.html
Copyright © 2011-2022 走看看