zoukankan      html  css  js  c++  java
  • 快速幂与矩阵快速幂学习笔记

           今天刷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;
    }
  • 相关阅读:
    异步非阻塞
    jdbc简单入门
    网络编程
    多线程
    java方法
    java之面向对象
    java-多线程
    Java之反射机制
    使用C#完成冒泡排序
    TextEdit不能空验证设置
  • 原文地址:https://www.cnblogs.com/wsblm/p/7989129.html
Copyright © 2011-2022 走看看