zoukankan      html  css  js  c++  java
  • 矩阵快速幂

    题目poj3070  http://poj.org/problem?id=3070

    题意很简单,就是斐波那契数列的求解,只不过输出的  f【n】(f【n】取模10000)  中的n足够大,暴力一定超时。

    题解:

      既然暴力会超时,那这里采用矩阵快速幂。

     

      对于斐波那契数列

      f【0】=0  f【1】=1

      当n大于等于2时,满足f【n】=f【n-1】+f【n-2】;

    然后对于矩阵A*B=C

    其中矩阵C【i】【j】    是矩阵A【i】【】 * B【】【j】得到的     (矩阵A的 i 行*   矩阵B的 j 列)

    f【3】=f【2】+f【1】

    是否可以写成

    进而

          然后递推得到

      

      

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define Mem0(x) memset(x,0,sizeof(x))
    #define Mem1(x) memset(x,-1,sizeof(x))
    #define MemX(x) memset(x,0x3f,sizeof(x))
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f;
    const double pi=acos(-1.0);
    
    const int mod=10000;
    struct Mul{
        int mt[3][3];
    }mat;
    
    int f[10];
    void init()
    {
        mat.mt[1][1]=mat.mt[1][2]=mat.mt[2][1]=1;
        mat.mt[2][2]=0;
        f[0]=0;
        f[1]=f[2]=1;
    }
    Mul mul(Mul node1,Mul node2)
    {
        Mul ans;
        ans.mt[1][1]=ans.mt[1][2]=ans.mt[2][1]=ans.mt[2][2]=0;
        for (int i=1;i<=2;i++){
            for (int j=1;j<=2;j++){
                for (int k=1;k<=2;k++){
                    ans.mt[i][j]=ans.mt[i][j]+node1.mt[i][k]*node2.mt[k][j]%mod;
                }
            }
        }
    /*    system("pause");
        for (int i=1;i<=2;i++){
            for (int j=1;j<=2;j++){
                cout<<ans.mt[i][j]<<" ";
            }
            cout<<endl;
        }*/
        return ans;
    }
    int quick_Mul(ll n)
    {
        Mul tmp;
        tmp.mt[1][1]=tmp.mt[2][2]=1;  //初始化单位矩阵
        tmp.mt[1][2]=tmp.mt[2][1]=0;
        while (n){
            if (n&1){
                tmp=mul(tmp,mat);
            }
            n>>=1;
            mat=mul(mat,mat);
        }
        return (tmp.mt[1][1]*f[1]+tmp.mt[1][2]*f[0])%mod;
    } 
    int main()
    {
        
        ll n;
        while (scanf("%lld",&n)&&(n!=-1)){
            init();
            if (n)
                cout<<quick_Mul(n-1)<<endl;
            else
                cout<<n<<endl;
        }
        return 0;
    }
  • 相关阅读:
    [原] 秋叶原随景
    ReportViewer不连接数据库,自定义DataSet导出到报表
    【程序人生】一个程序员对学弟学妹建议(转)
    c#钩子学习笔记(一)
    解决关于多客户端操作数据库并发问题
    SQL Server 存储过程
    有关抽奖的一个算法
    c#发送邮件含附件
    CrystalReport不连接数据库,自定义DataSet导出到水晶报表
    c#钩子学习笔记(二)
  • 原文地址:https://www.cnblogs.com/q1204675546/p/10705630.html
Copyright © 2011-2022 走看看