快速幂与矩阵快速幂学习笔记

       今天刷51nod的时候写到了https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1242的斐波那契数列问题,发现我竟然已经忘掉了快速幂模版(QAQ)于是复习了一下:

  快速幂就贴一下模版吧

int poww(int a,int b){
   int ans=1,base=a;
    while(b!=0){
        if(b&1!=0)
       ans*=base;
       base*=base;
        b>>=1;
   }
   return ans;
 }

这个模版就是求a^b所用的快速幂模版,具体数据根据题目修改。

然后就是矩阵快速幂了,矩阵快速幂相比普通快速幂运算将数的幂变成了矩阵幂,一般模版是这样的

jz cf(jz x,jz y)
{
    jz neww;
    neww.a[0][0]=0;
    neww.a[0][1]=0;
    neww.a[1][0]=0;
    neww.a[1][1]=0;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        for(int k=0; k<2; k++)  
            {  
                neww.a[i][j]+=x.a[i][k]*y.a[k][j];  
                neww.a[i][j]%=mod;  
            }  
    }
    return neww;
}

于快速幂相对应,把乘法的幺元1改成单位矩阵,模拟两矩阵相乘的过程。

我看到这里的时候是一脸懵逼的,这跟斐波那契数列有啥关系啊。。

然后我在网上找到了公式。。。

来自网络

然后就惊了。果然线代要好好学啊(QWQ)

最后返回值的左下角或右上角的数值就是答案了~~记得取模

总代码:

#include<iostream>
using namespace std;
#define mod 1000000009
struct jz
{
    long long a[2][2];
};
jz bz;
jz cf(jz x,jz y)
{
    jz neww;
    neww.a[0][0]=0;
    neww.a[0][1]=0;
    neww.a[1][0]=0;
    neww.a[1][1]=0;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        for(int k=0; k<2; k++)  
            {  
                neww.a[i][j]+=x.a[i][k]*y.a[k][j];  
                neww.a[i][j]%=mod;  
            }  
    }
    return neww;
}
jz poww(long long b)
{
    jz ans;
    ans.a[0][0]=1;
    ans.a[1][1]=1;
    ans.a[1][0]=0;
    ans.a[0][1]=0;
         while(b!=0)
    {
        if(b&1!=0)
        ans=cf(ans,bz);
        bz=cf(bz,bz);
        b>>=1;
     }
   return ans;
}
int main()
{
    long long s;
    cin>>s;
    bz.a[0][0]=1;
    bz.a[0][1]=1;
    bz.a[1][0]=1;
    bz.a[1][1]=0;
    jz aaa;
    aaa=poww(s);
    cout<<aaa.a[0][1]<<endl;
}
原文地址:https://www.cnblogs.com/wsblm/p/7989129.html